vue脚手架实现留言板功能
vue脚手架实现简单的留言板功能
·
利用vue-cli创建的vue脚手架,实现留言板功能
1.搭建项目结构
命令行中创建vue项目,在src路径下的assets文件夹中创建images文件夹存放用户头像,并新建一个pages文件夹用于存放自己的vue文件。
项目初始结构如图
2.创建组件
在pages文件夹中创建Album
、Article
、Home
、UCenter
、Message
五个组件,分别对应相册,文章,主页,个人中心,留言板。
3.编辑组件
编辑除留言板(Message.vue)
之外的所有组件,此案例只针对留言板功能
编辑其他页面组件代码如下:
<template>
<div class="home">
<h2>主页页面</h2>
</div>
</template>
<script>
export default {
data() {
return {};
},
};
</script>
<style>
</style>
编辑App.vue
,导入并注册组件,编写页面结构,修改页面样式
<template>
<div id="app">
<h2>个人空间</h2>
<ul class="nav">
<li :class="{ active: page === 'Home' }" @click="page = 'Home'">主页</li>
<li :class="{ active: page === 'Article' }" @click="page = 'Article'">
文章
</li>
<li :class="{ active: page === 'Album' }" @click="page = 'Album'">
相册
</li>
<li :class="{ active: page === 'Message' }" @click="page = 'Message'">
留言板
</li>
<li :class="{ active: page === 'Ucenter' }" @click="page = 'Ucenter'">
个人中心
</li>
</ul>
<hr />
<keep-alive>
<component :is="page"></component>
</keep-alive>
</div>
</template>
<script>
import Album from "./pages/Album.vue";
import Article from "./pages/Article.vue";
import Home from "./pages/Home.vue";
import Message from "./pages/Message.vue";
import Ucenter from "./pages/Ucenter.vue";
export default {
name: "App",
components: {
Album,
Article,
Home,
Message,
Ucenter,
},
data() {
return {
page: "Home",
};
},
};
</script>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
html,
body {
background-color: #eee;
}
.nav {
margin: 50px 0;
height: 50px;
background-color: antiquewhite;
font-size: 22px;
display: flex;
list-style: none;
}
.nav li {
line-height: 40px;
padding: 5px 20px;
cursor: pointer;
}
.nav li:hover {
font-weight: bold;
}
.nav li.active {
color: orangered;
border-bottom: 2px solid orangered;
}
</style>
编辑Message.vue
,代码如下
<template>
<div class="message">
<h2>留言板</h2>
<div class="input-msg">
<textarea name="" id="msg" cols="50" rows="5" v-model.trim="content" @keyup.enter="sendMsg" placeholder="请输入评论内容"></textarea>
<button class="send-msg" @click="sendMsg">发送留言</button>
</div>
<div class="history">
<div class="msg-item" v-for="msg in msgList" :key="msg.id">
<img class="header-img" :src="msg.img" alt="">
<div>
<h2>作者:{{msg.author}}<small>{{msg.time | formatTime}}</small></h2>
<p class="cont">{{msg.content}}</p>
<p class="control">
<button class="btn btn-edit" @click="editMsg(msg)">编辑</button>
<button class="btn btn-del" @click="delMsg(msg.id)">删除</button>
</p>
</div>
</div>
<!-- <div class="msg-item">
<img class="header-img" src="../assets/images/1.webp" alt="">
<div>
<h2>作者:豆子<small>2022-10-14 15:03:26</small></h2>
<p>留言内容</p>
</div>
</div> -->
</div>
</div>
</template>
<script>
// 限于纯前端测试时使用
import m1 from "../assets/images/1.jpg"
import m2 from "../assets/images/2.jpg"
import m3 from "../assets/images/3.jpg"
import m4 from '../assets/images/4.jpg'
export default {
created(){
// 当前实例创建时,模拟从接口获取数据
this.msgList=[
{id:3,author: "尔尔",time:Date.now(),img:m1,content:"我也爱你!"},
{id:2,author: "依依",time:Date.now(),img:m2,content:"我爱你!"},
{id:1,author: "思思",time:Date.now(),img:m3,content:"我爱你爱你!"},
];
},
data(){
return{
// 双向绑定的留言内容
content: "",
// 留言内容
msgList: [],
// 声明编辑的id
editId:""
}
},
methods: {
sendMsg () {
// console.log("用户准备发表留言",this.content)
if(this.content===""){
alert("留言内容为空")
return
}
if(this.editId){
// 拆分数据
let [content]=this.content.split(" ")
let index = this.msgList.findIndex(msg=>msg.id === this.editId)
this.msgList[index].content=content
// 清空文本域、清空editId
this.content=""
this.editId=""
}else {
// 创建留言对象
let id=this.msgList.length>0?this.msgList[0].id+1:1
let m={id,author:"豆子",time: Date.now(),img:m4,content:this.content}
// 添加留言
this.msgList.unshift(m)
// 清空留言框
this.content=""
}
},
editMsg(msg) {
// 给编辑的id赋值
this.editId = msg.id
// 给输入框绑定的变量赋值(展示编辑数据)
this.content = msg.content
},
delMsg(id) {
// 二次确认
const result = confirm("确认删除?")
if (!result) return
// 删除
this.msgList = this.msgList.filter(msg => msg.id !== id)
// 防止点击编辑之后在点击删除按钮出现的bug
this.editId=""
this.content=""
},
},
filters: {
formatTime:value=>{
const date=new Date(value)
return `${date.getFullYear()}年${(date.getMonth()+1).toString().padStart(2,0)}月${date.getDate().toString().padStart(2,0)}日 ${date.getHours().toString().padStart(2,0)}时${date.getMinutes().toString().padStart(2,0)}分${date.getSeconds().toString().padStart(2,0)}秒`
}
}
}
</script>
<!-- 如果想让这里编写的样式只对当前组件有效,style上添加一个scoped属性-->
<style scoped>
.input-msg{
width: 80%;
margin: 10px auto;
display: flex;
flex-direction: column;
align-items: flex-end;
}
#msg{
width: 100%;
height: 180px;
padding: 10px;
outline: none;
border: 1px solid rgba(219, 73, 73, 0.466);
border-radius: 5px;
resize: none;
display: block;
margin: 10px auto;
font-size: 18px;
}
.send-msg{
width: 200px;
height: 40px;
border: none;
background-color: orangered;
color: wheat;
border-radius: 20px;
cursor: pointer;
font-size: 18px;
}
.send-msg:hover{
background-color: rgb(34, 231, 109);
color: #000;
}
.history{
width: 80%;
padding: 20px 10px;
margin: 10px auto;
background-color: #fff;
}
.msg-item{
display: flex;
padding: 10px;
border-bottom: 1px dashed #888;
}
.msg-item img{
width: 100px;
height: 100px;
border-radius: 10px;
}
.msg-item div{
margin-left: 10px;
width: 100%;
}
.msg-item div h2{
font-size: 22px;
}
.msg-item div h2 small{
font-size: 16px;
color: #888;
font-weight: 600;
margin-left: 20px;
}
.msg-item div p.cont{
font-size: 16px;
color: #444;
margin: 10px 0;
word-wrap: break-word;
word-wrap: break-word;
white-space: pre-wrap;
min-height: 50px;
/* border: 1px solid red; */
}
.control{
width: 100%;
display: flex;
justify-content: flex-end;
}
.btn{
width: 80px;
height: 30px;
border: 1px solid #888;
border-radius: 15px;
cursor: pointer;
}
.btn-edit{
background-color: rgb(20, 187, 247);
}
.btn-edit:hover{
background-color: rgb(17, 148, 196);
color: #fff;
}
.btn-del{
background-color: rgb(247, 20, 88);
}
.btn-del:hover{
background-color: rgb(192, 21, 72);
color: #fff;
}
</style>
浏览器效果如图
更多推荐
已为社区贡献2条内容
所有评论(0)