有一个页面,下边是评论列表,展示用户的评论。在上面有一个发表框,有一发表按钮,一点击,就发展成功,展示到下方的评论框。存储用localStorage
- 第一步,先把布局写出来
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>发表评论</title>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<link rel="stylesheet" href="../bootstrap/css/bootstrap.min.css">
</head>
<body>
<div id="app">
<ul class="list-group">
<li class="list-group-item" v-for="(item, index) in list" :key = "item.id">
<span class="badge">评论人:{{ item.user }}</span>
{{ item.content }}
</li>
</ul>
</div>
</body>
</html>
<script>
new Vue({
el: "#app",
data: {
list: [
{id: Date.now(),user:"李白",content:"天生我才必有用"},
{id: Date.now(),user:"江小白",content:"劝君更进一杯酒"},
{id: Date.now(),user:"小马",content:"我行马,风吹草低见牛羊的马"},
],
},
methods: {
}
});
</script>

接着写发表评论的框
这个框,咱写成一个组件
<comment-box></comment-box>
......
<template id="comment">
<div>
<div class="form-group">
<label for="">评论人:</label>
<input type="text" class="form-control">
</div>
<div class="form-group">
<label for="">评论内容:</label>
<textarea class="form-control"></textarea>
</div>
<div class="form-group">
<input type="button" class="btn btn-primary" value="发表评论">
</div>
</div>
</template>
......
<script>
var commentBox = Vue.component("comment",{
template: "#comment"
});
new Vue({
el: "#app",
data: {
list: [
{id: Date.now(),user:"李白",content:"天生我才必有用"},
{id: Date.now(),user:"江小白",content:"劝君更进一杯酒"},
{id: Date.now(),user:"小马",content:"我行马,风吹草低见牛羊的马"},
],
},
methods: {
},
components: {
commentBox
}
});
</script>

实现发表功能
需要使用双向数据绑定,获取用户输入的评论人和评论内容,再讲这些数组合成一个object,push到我们数组list的最后面
<input type="text" class="form-control" v-model="user">
<textarea class="form-control" v-model="content"></textarea>
<input type="button" class="btn btn-primary" value="发表评论" @click="postComment">
........
var commentBox = Vue.component("comment",{
template: "#comment",
data: function(){
return {
user: "",
content:"",
}
},
methods: {
postComment(){
let object = {id: Date.now(), user: this.user,content: this.content};
this.list.push(object);
}
},
});

有老师带着写,就是不一样
分析发表评论的逻辑
- 1.评论数据存到哪里去,存到localStorage里
- 2.先组织出一个最新的评论数据
- 3.把第二步中得到的评论对象保存到localStorage里面去
- 3.1 localStorage只支持存放字符串数据,要先调用JSON.stringfy序列化
- 3.2在保存最新的评论数据之前,要先获取以前的评论数据(String类型),转为一个数组对象(JSON.parse函数),然后把最新的评论unshift存到数组最前面
- 3.3如果以前没有发表过的话,JSON.parse的时候就会报错---3.2步会有一个潜在的bug,如果localStorage里的评论数组转为空或不存在的时候,则可以返回一个"[]"让JSON.parse去转换
- 3.4把最新的评论列表数据再次调用JSON.stringfy转为数组字符转,调用lolcaStorage.setItem()存储。
子组件的methods:
methods: {
postComment(){
let comment = {id: Date.now(), user: this.user,content: this.content};
var list = JSON.parse(localStorage.getItem("cmts") || "[]");
list.unshift(comment);
localStorage.setItem("cmts",JSON.stringify(list));
this.user = this.content = "";
}
},

最后,我们让vue自动渲染一下页面
父组件里边有刷新页面数据的方法,但它不知道什么时候调用;子组件知道点击“发表评论”按钮时刷新页面数据,但它没有刷新页面数据的方法。这里涉及到了父子组件之间的函数传递
<comment-box @fn1="localComments"></comment-box>
......
var commentBox = Vue.component("comment",{
......
methods: {
postComment(){
let comment = {id: Date.now(), user: this.user,content: this.content};
var list = JSON.parse(localStorage.getItem("cmts") || "[]");
list.unshift(comment);
localStorage.setItem("cmts",JSON.stringify(list));
this.user = this.content = "";
this.$emit("fn1");
}
},
});
new Vue({
el: "#app",
......
methods:{
localComments(){
this.list = JSON.parse(localStorage.getItem("cmts") || "[]");
},
},
created() {
this.localComments();
},
});

网友评论