未分模块化
html
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>评论模块</title> <style> #root{ width: 400px; padding: 2em; margin: 2em auto; border: 1px solid #e0e0e0; border-radius: 1em; } label{ display: flex; margin: 1em 0; } </style> </head> <body> <div id="root"> <c-input @wybc='zhendeyaobaocuoa'></c-input> <c-list :comments="comments" @dodel="zhendeshanc"></c-list> </div> <script src="js/comment-input.js"></script> <script src="js/comment-list.js"></script> <script src="js/Vue.js"></script> <script> Vue.component('c-input',commentInput); Vue.component('c-list',commentList); Vue.component('comment',commentItem); var app = new Vue({ el:"#root", data:{ comments:[ ] }, methods:{ zhendeyaobaocuoa(res){ this.comments.push(res); this.updaLocalStorage(); }, updaLocalStorage(){ localStorage.setItem("data",JSON.stringify(this.comments)); }, zhendeshanc(id){ this.comments=this.comments.filter((c) => c.id!=id) this.updaLocalStorage(); } }, created(){ const cs=localStorage.getItem("data"); if(cs){ this.comments=JSON.parse(cs); } } }) </script> </body> </html>
comment-input.js
var commentInput={ template:` <div class='cinput'> <label> <span>用户名</span> <input v-model='author'/> </label> <label> <span>评论内容</span> <textarea v-model='content'></textarea> </label> <button @click='doSave()'>发布</button> </div> `, data(){ return { author:'', content:'' }}, methods:{ doSave(){ this.$emit('wybc',{ id:+new Date(), author:this.author, content:this.content }) } } }
comment-list.js
var commentList={ props:['comments'], template:` <div class='clist'> <comment v-for='c in comments' v-bind:comment='c' @dodel="dodel"> </comment> </div> `, methods:{ dodel(id){ this.$emit("dodel",id); } } }; var commentItem={ props:['comment'], template:` <div> {{comment.author}}: <span ></span> <span>{{comment.content}}</span> <a href @click.prevent='del'>删除</a> </div> `, methods:{ del(){ this.$emit("dodel",this.comment.id); } } }
分好模块化
html
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8"/> <title>评论模块</title> <link rel="stylesheet" href="css/index.css"> <script src="https://cdn.bootcss.com/vue/2.5.13/vue.js"></script> </head> <body> <div id="root"> <comment></comment> </div> <script type="module"> import commentComp from './component/comment/comment-comp.js'; Vue.component('comment', commentComp); var vm = new Vue({ el: '#root' }); </script> </body> </html>
comment-comp.js
import commentInput from './comment-input.js'; import commentList from './comment-list.js'; export default { template:` <div> <cinput @wybc='zhendeyaobaocuoa' ></cinput> <clist :comments="comments" @dodel="zhendeshanc"></clist> </div>`, data() { return { comments: [] }}, methods:{ zhendeyaobaocuoa(res){ this.comments.push(res); this.updaLocalStorage(); }, updaLocalStorage(){ localStorage.setItem("data",JSON.stringify(this.comments)); }, zhendeshanc(id){ this.comments=this.comments.filter((c) => c.id!=id) this.updaLocalStorage(); } }, created(){ const cs=localStorage.getItem("data"); if(cs){ this.comments=JSON.parse(cs); } }, components:{ cinput:commentInput, clist:commentList } }
注意
comment-input.js
var commentInput={ template:` <div class='cinput'> <label> <span>用户名</span> <input v-model='author'/> </label> <label> <span>评论内容</span> <textarea v-model='content'></textarea> </label> <button @click='doSave()'>发布</button> </div> `, data(){ return { author:'', content:'' }}, methods:{ doSave(){ this.$emit('wybc',{ id:+new Date(), author:this.author, content:this.content }) } } } export default commentInput;
comment-item.js
export default { props:['comment'], template:` <div> {{comment.author}}: <span ></span> <span>{{comment.content}}</span> <a href @click.prevent='del'>删除</a> </div> `, methods:{ del(){ this.$emit("dodel",this.comment.id); } } };
comment-list.js
import commentItem from './comment-item.js'; export default{ props:['comments'], template:` <div class='clist'> <comment v-for='c in comments' v-bind:comment='c' @dodel="dodel" v-bind:key=c.id> </comment> </div> `, methods:{ dodel(id){ this.$emit("dodel",id); } }, components: { comment: commentItem } };
index.css
#root { width: 400px; padding: 2em; margin: 2em auto; border: 1px solid #e0e0e0; border-radius: 1em; } .cinput { margin-bottom: 1em; } label { display: flex; margin: 1em 0; } label span { flex-basis: 100px; } input, textarea { flex: 1; } .cinput footer { text-align: right; } .cinput button { border: none; background-color: orange; padding: .4em 1em; color: white; font-size: 16px; border-radius: 3px; box-shadow: 1px 1px 1px #e0e0e0; } .comment { padding: 1em; border-bottom: 1px solid #f0f0f0; display: flex; } .comment-author { color: steelblue; flex-basis: 80px; } .comment-delete { margin-left: auto; }