Vue 小Demo——留言板

通过id来引用模板</li><li>第二种:使用template标签 :<template id="myComponent">通过id来引用模板。HTML5才有template标签,IE未实现此标签。</li><li>第三种:单文件组件( .vue格式文件)。适用与大型复杂的项目。</li></ol><p>这个小demo 就使用简单的 script标签方式来写vue组件模板啦。</p><p>先看一下成品展示:</p><ol><li>首先制作静态页:</li></ol><div class="pgc-img"><img src="http://p1.pstatp.com/large/pgc-image/1530545783570be10d4eb2a" img_width="695" img_height="482" alt="Vue 小Demo——留言板" inline="0"><p class="pgc-img-caption"></p></div><p>制作动态页:</p><p>抽象出组件:抽象出三个组件 input组件,textarea组件,留言列表组件</p><p>input组件</p><p>编写模板</p><div class="pgc-img"><img src="http://p3.pstatp.com/large/pgc-image/15305462491546bdffe158e" img_width="569" img_height="161" alt="Vue 小Demo——留言板" inline="0"><p class="pgc-img-caption"></p></div><p>注册组件</p><div class="pgc-img"><img src="http://p1.pstatp.com/large/pgc-image/153054635817835d676e2e2" img_width="306" img_height="204" alt="Vue 小Demo——留言板" inline="0"><p class="pgc-img-caption"></p></div><p>使用组件</p><div class="pgc-img"><img src="http://p9.pstatp.com/large/pgc-image/153054644014891e7c805e9" img_width="266" img_height="42" alt="Vue 小Demo——留言板" inline="0"><p class="pgc-img-caption"></p></div><p>textarea 和留言列表组件:</p><div class="pgc-img"><img src="http://p3.pstatp.com/large/pgc-image/1530630664106e6909090d5" img_width="494" img_height="331" alt="Vue 小Demo——留言板" inline="0"><p class="pgc-img-caption"></p></div><p>注册组件:</p><div class="pgc-img"><img src="http://p3.pstatp.com/large/pgc-image/153063070930535739a2f86" img_width="284" img_height="147" alt="Vue 小Demo——留言板" inline="0"><p class="pgc-img-caption"></p></div><p>使用组件</p><div class="pgc-img"><img src="http://p3.pstatp.com/large/pgc-image/15306307540875c6c03810d" img_width="472" img_height="193" alt="Vue 小Demo——留言板" inline="0"><p class="pgc-img-caption"></p></div><p>2.填充数据:</p><p>使用 v-model 指令在表单 <input> 及 <textarea> 元素上创建双向数据绑定。它会根据控件类型自动选取正确的方法来更新元素。</p><p>username 和 message 数据属性 保存输入的值.</p><div class="pgc-img"><img src="http://p9.pstatp.com/large/pgc-image/1530630893639269217c7a7" img_width="550" img_height="39" alt="Vue 小Demo——留言板" inline="0"><p class="pgc-img-caption"></p></div><div class="pgc-img"><img src="http://p3.pstatp.com/large/pgc-image/1530630905884a8a20ac331" img_width="328" img_height="34" alt="Vue 小Demo——留言板" inline="0"><p class="pgc-img-caption"></p></div><div class="pgc-img"><img src="http://p1.pstatp.com/large/pgc-image/1530630919238a5e6c83287" img_width="332" img_height="340" alt="Vue 小Demo——留言板" inline="0"><p class="pgc-img-caption"></p></div><p>v-model是语法糖,对inout事件的包装,相当于:</p><div class="pgc-img"><img src="http://p1.pstatp.com/large/pgc-image/1530630994444fb881e8c73" img_width="695" img_height="35" alt="Vue 小Demo——留言板" inline="0"><p class="pgc-img-caption"></p></div><div class="pgc-img"><img src="http://p1.pstatp.com/large/pgc-image/1530631014946beb4d7c2c8" img_width="518" img_height="266" alt="Vue 小Demo——留言板" inline="0"><p class="pgc-img-caption"></p></div><p>发布功能:</p><p>发布公能是 拿到输入的 昵称(username) 和 留言内容(message),填充到 留言板列表中。昵称和留言内容分别在 v-input 和 v-textarea组件中,而 按钮在 根组件中,与v-input和v-textarea为兄弟关系。 所以我们将 昵称 和留言 提取到 v-input v-textarea的父组件——根组件中。</p><div class="pgc-img"><img src="http://p3.pstatp.com/large/pgc-image/1530631203411ca1634c0bc" img_width="272" img_height="195" alt="Vue 小Demo——留言板" inline="0"><p class="pgc-img-caption"></p></div><p>通过 v-model指令,将昵称 和 留言内容,绑定到对应的子组件上去。</p><div class="pgc-img"><img src="http://p1.pstatp.com/large/pgc-image/153063126411244e3899a3b" img_width="385" img_height="47" alt="Vue 小Demo——留言板" inline="0"><p class="pgc-img-caption"></p></div><p>将v-model的值 绑定到 子组件中props中的 value属性上。父组件通过props向子组件传递数据。</p><div class="pgc-img"><img src="http://p1.pstatp.com/large/pgc-image/15306313717884b5adb9d7a" img_width="267" img_height="162" alt="Vue 小Demo——留言板" inline="0"><p class="pgc-img-caption"></p></div><p>在子组件中使用组件上v-model指令绑定的数据,input和 textarea标签需要使用,所以:</p><p>修改input标签元素,并删除v-input组件中的 data属性,这个不需要了:</p><div class="pgc-img"><img src="http://p1.pstatp.com/large/pgc-image/1530631526924029e2d6c54" img_width="917" img_height="49" alt="Vue 小Demo——留言板" inline="0"><p class="pgc-img-caption"></p></div><p>将 props.value 绑定到 input元素的value属性上 :value 指向input元素的value属性。”value" 中的value指向 props中的value。input元素上 监听input事件。input事件调用父组件的input事件来更新值。</p><p>对比一下可以发现v-model指令使用在html标签上 和 使用在 组件之上是不一样的。当v-model指令 用在组件上的时候,跟用在DOM元素上的使用方式并不一样,在DOM元素上使用v-model时,Vue帮我们实现了语法糖。在组件上使用v-model,Vue帮我们实现了一半的语法糖,剩下一半需要我们自己实现 。</p><p>其实就是这样 :</p><div class="pgc-img"><img src="http://p3.pstatp.com/large/pgc-image/1530631808648bd950e4086" img_width="556" img_height="29" alt="Vue 小Demo——留言板" inline="0"><p class="pgc-img-caption"></p></div><div class="pgc-img"><img src="http://p3.pstatp.com/large/pgc-image/1530631826880a51308bafa" img_width="471" img_height="307" alt="Vue 小Demo——留言板" inline="0"><p class="pgc-img-caption"></p></div><div class="pgc-img"><img src="http://p1.pstatp.com/large/pgc-image/15306318494827af97b1ea7" img_width="297" img_height="166" alt="Vue 小Demo——留言板" inline="0"><p class="pgc-img-caption"></p></div><p>1. 将根组件(根实例可以看作根组件)中的 message 绑定到 子组件v-input中的 props中的 value中 。</p><p>2. 将根组件中的 updataUsernameEvent 方法注册到 子组件中的 input事件上。</p><p>子组件v-input :</p><div class="pgc-img"><img src="http://p3.pstatp.com/large/pgc-image/15306319874726fab3376b5" img_width="831" img_height="134" alt="Vue 小Demo——留言板" inline="0"><p class="pgc-img-caption"></p></div><div class="pgc-img"><img src="http://p3.pstatp.com/large/pgc-image/1530631998926919b4f9e7d" img_width="498" img_height="257" alt="Vue 小Demo——留言板" inline="0"><p class="pgc-img-caption"></p></div><p>1.将v-input中的 props中的 value属性 绑定到 input标签中的 value属性上。</p><p>2.将v-input中的方法 childrenInputEvent 方法 注册 到inpu标签中的input事件上。</p><p>v-input中的childrenInputEvent 方法触发 父组件(根组件)注册到子组件上的input事件,调用updateUsernameEvent来修改 username属性的值</p><div class="pgc-img"><img src="http://p3.pstatp.com/large/pgc-image/15306321108359525f6881f" img_width="543" img_height="29" alt="Vue 小Demo——留言板" inline="0"><p class="pgc-img-caption"></p></div><p>看下效果:</p><div class="pgc-img"><img src="http://p9.pstatp.com/large/pgc-image/15306322091067f0054efa3" img_width="914" img_height="654" alt="Vue 小Demo——留言板" inline="0"><p class="pgc-img-caption"></p></div><p>v-model指令语法糖的形式如下:</p><div class="pgc-img"><img src="http://p3.pstatp.com/large/pgc-image/1530632250881d19d669db2" img_width="283" img_height="187" alt="Vue 小Demo——留言板" inline="0"><p class="pgc-img-caption"></p></div><div class="pgc-img"><img src="http://p9.pstatp.com/large/pgc-image/15306322862356e48976db6" img_width="331" img_height="31" alt="Vue 小Demo——留言板" inline="0"><p class="pgc-img-caption"></p></div><p>子组件:</p><div class="pgc-img"><img src="http://p9.pstatp.com/large/pgc-image/1530632307693db0aeefa55" img_width="465" img_height="257" alt="Vue 小Demo——留言板" inline="0"><p class="pgc-img-caption"></p></div><div class="pgc-img"><img src="http://p3.pstatp.com/large/pgc-image/1530632317216213bcab162" img_width="805" img_height="127" alt="Vue 小Demo——留言板" inline="0"><p class="pgc-img-caption"></p></div><p>子组件还可以简写成这样:</p><div class="pgc-img"><img src="http://p3.pstatp.com/large/pgc-image/15306323444069bd793ea0a" img_width="262" img_height="159" alt="Vue 小Demo——留言板" inline="0"><p class="pgc-img-caption"></p></div><div class="pgc-img"><img src="http://p3.pstatp.com/large/pgc-image/1530632349755302aaaac3f" img_width="942" img_height="133" alt="Vue 小Demo——留言板" inline="0"><p class="pgc-img-caption"></p></div><p>对比一下 可以发现 在组件上使用v-model指令时,Vue帮我们实现了一半的语法糖 :</p><p>v-model指令语法糖形式</p><div class="pgc-img"><img src="http://p9.pstatp.com/large/pgc-image/15306323724655bf52d9ca9" img_width="331" img_height="31" alt="Vue 小Demo——留言板" inline="0"><p class="pgc-img-caption"></p></div><p>没用使用v-model指令语法糖形式 :</p><div class="pgc-img"><img src="http://p1.pstatp.com/large/pgc-image/15306324686426169a60bd7" img_width="556" img_height="29" alt="Vue 小Demo——留言板" inline="0"><p class="pgc-img-caption"></p></div><p>子组件中 Vue没用帮我们实现语法糖,所以我们需要我们自己实现:</p><div class="pgc-img"><img src="http://p3.pstatp.com/large/pgc-image/1530632505524c3fea578f6" img_width="942" img_height="133" alt="Vue 小Demo——留言板" inline="0"><p class="pgc-img-caption"></p></div><p>v-textarea组件同样如此。</p><p>点击发布按钮,将 username 与 message 存储到 留言列表中 :</p><div class="pgc-img"><img src="http://p9.pstatp.com/large/pgc-image/1530632733269562d2e665e" img_width="558" img_height="552" alt="Vue 小Demo——留言板" inline="0"><p class="pgc-img-caption"></p></div><p>做一些验证判断,将 username 与 message 存储到 留言列表中,并清空输入内容。将handleSend方法注册到 button标签元素的点击事件上。</p><p>使用push将数据插入数组中来触发视图更新。一定不要使用不能触发Vue视图更新的方式来修改更新数组!</p><p>Vue 不能检测以下变动的数组:</p><ol><li>当你利用索引直接设置一个项时,例如:vm.items[indexOfItem] = newValue</li><li>当你修改数组的长度时,例如:vm.items.length = newLength</li></ol><p>数组更新检测Vue官方文档 列表渲染 一节中有详细的介绍</p><div class="pgc-img"><img src="http://p3.pstatp.com/large/pgc-image/153063277673288a0bcdd7f" img_width="345" img_height="31" alt="Vue 小Demo——留言板" inline="0"><p class="pgc-img-caption"></p></div><p>渲染留言列表:</p><p>绑定留言列表 list到 留言板v-list组件上:</p><div class="pgc-img"><img src="http://p3.pstatp.com/large/pgc-image/15306328197714412255238" img_width="294" img_height="34" alt="Vue 小Demo——留言板" inline="0"><p class="pgc-img-caption"></p></div><p>注册v-list组件:</p><div class="pgc-img"><img src="http://p1.pstatp.com/large/pgc-image/15306328377937b82d744fa" img_width="325" img_height="283" alt="Vue 小Demo——留言板" inline="0"><p class="pgc-img-caption"></p></div><p>使用v-for渲染留言板:</p><div class="pgc-img"><img src="http://p3.pstatp.com/large/pgc-image/15306328674397e3c3580ca" img_width="579" img_height="217" alt="Vue 小Demo——留言板" inline="0"><p class="pgc-img-caption"></p></div><p>效果如下:</p><div class="pgc-img"><img src="http://p3.pstatp.com/large/pgc-image/1530635011375c638386ba9" img_width="693" img_height="632" alt="Vue 小Demo——留言板" inline="0"><p class="pgc-img-caption"></p></div><p>回复功能:</p><p>回复同样也是 将回复信息储存到留言列表中,所以将回复公能也放到 根组件中;</p><div class="pgc-img"><img src="http://p1.pstatp.com/large/pgc-image/1530635048938ec62323782" img_width="440" img_height="221" alt="Vue 小Demo——留言板" inline="0"><p class="pgc-img-caption"></p></div><p>将handleReply方法注册到 v-list组件中的 reply事件上。</p><div class="pgc-img"><img src="http://p3.pstatp.com/large/pgc-image/1530635069855676c72eae9" img_width="452" img_height="42" alt="Vue 小Demo——留言板" inline="0"><p class="pgc-img-caption"></p></div><p>通过点击事件来触发 reply事件</p><div class="pgc-img"><img src="http://p3.pstatp.com/large/pgc-image/1530635089724f3068b616d" img_width="483" img_height="33" alt="Vue 小Demo——留言板" inline="0"><p class="pgc-img-caption"></p></div><div class="pgc-img"><img src="http://p3.pstatp.com/large/pgc-image/1530635100781ec81c97d5b" img_width="453" img_height="294" alt="Vue 小Demo——留言板" inline="0"><p class="pgc-img-caption"></p></div><p>点击回复按钮时候,我们需要触发input标签的焦点事件。我们怎么拿到 input标签元素呢?可以给 input标签做一个 标记:通过ref属性拿到所标记的元素或者组件实例:</p><div class="pgc-img"><img src="http://p3.pstatp.com/large/pgc-image/1530635155072eed9935ce7" img_width="639" img_height="53" alt="Vue 小Demo——留言板" inline="0"><p class="pgc-img-caption"></p></div><p>通过 Vue的 $refs实例属性来访问 注册过 ref 特性 的所有 DOM 元素和组件实例。 如果在普通的 DOM 元素上使用,引用指向的就是 DOM 元素;如果用在子组件上,引用就指向组件实例</p><div class="pgc-img"><img src="http://p3.pstatp.com/large/pgc-image/1530635179382f877ed980f" img_width="482" img_height="277" alt="Vue 小Demo——留言板" inline="0"><p class="pgc-img-caption"></p></div><p>通过 Vue的$refs实例属性来访问 input标签元素,并触发其焦点事件。$refs实例属性 只能访问 当前组件作用域内的(组件html模板内部) ref标签,无法被外部访问,父组件也不可以。</p><p>无法访问</p><div class="pgc-img"><img src="http://p3.pstatp.com/large/pgc-image/15306351968194615cf4e0c" img_width="472" img_height="340" alt="Vue 小Demo——留言板" inline="0"><p class="pgc-img-caption"></p></div><p>因此我们需要先拿到子组件,然后在通过子组件去拿着子组件中ref标记的html元素标签。</p><p>给子组件加一个 ref标记:</p><div class="pgc-img"><img src="http://p1.pstatp.com/large/pgc-image/15306352231780d17a4a3c2" img_width="452" img_height="32" alt="Vue 小Demo——留言板" inline="0"><p class="pgc-img-caption"></p></div><p>通过 refs拿到子组件实例,调用子组件中的方法:</p><div class="pgc-img"><img src="http://p3.pstatp.com/large/pgc-image/15306352404949710adc03d" img_width="473" img_height="324" alt="Vue 小Demo——留言板" inline="0"><p class="pgc-img-caption"></p></div><p>子组件通过 refs 拿到作用域内的 ref标记,(input标签元素)并触发焦点事件</p><div class="pgc-img"><img src="http://p1.pstatp.com/large/pgc-image/15306352620341322eb9463" img_width="410" img_height="279" alt="Vue 小Demo——留言板" inline="0"><p class="pgc-img-caption"></p></div><p>看下效果:</p><div class="pgc-img"><img src="http://p1.pstatp.com/large/pgc-image/1530635303271c66814b477" img_width="693" img_height="632" alt="Vue 小Demo——留言板" inline="0"><p class="pgc-img-caption"></p></div><p>在增加一个删除留言的功能:</p><div class="pgc-img"><img src="http://p3.pstatp.com/large/pgc-image/15306353411904a9f363a9a" img_width="476" img_height="415" alt="Vue 小Demo——留言板" inline="0"><p class="pgc-img-caption"></p></div><p>注册到子组件的 delete事件上:</p><div class="pgc-img"><img src="http://p1.pstatp.com/large/pgc-image/1530635361171b71ecc7d95" img_width="646" img_height="40" alt="Vue 小Demo——留言板" inline="0"><p class="pgc-img-caption"></p></div><p>通过点击事件触发 注册的 delete事件:</p><div class="pgc-img"><img src="http://p1.pstatp.com/large/pgc-image/153063544743526c821877e" img_width="707" img_height="62" alt="Vue 小Demo——留言板" inline="0"><p class="pgc-img-caption"></p></div><div class="pgc-img"><img src="http://p9.pstatp.com/large/pgc-image/153063537966810a9a7e8ec" img_width="411" img_height="361" alt="Vue 小Demo——留言板" inline="0"><p class="pgc-img-caption"></p></div><p>看下效果:</p><div class="pgc-img"><img src="http://p3.pstatp.com/large/pgc-image/153063551513112e963642d" img_width="693" img_height="632" alt="Vue 小Demo——留言板" inline="0"><p class="pgc-img-caption"></p></div><p>好了 一个简单的留言板功能我们实现完了。</p></div>