一个留言板小demo,题目来自 《Vue.js实战》第九章 9.7实战:留言板。
有人想看源码,源码已上传GitHub
GitHub地址 https://github.com/zhaiyifei/VueDemo.git
头条怎么插超链啊(捂脸)
看下需求:
- 输入昵称,以及留言内容,都不允许为空。
- 发布留言内容到 留言板中。
- 留言回复。
Vue组件模板有3种书写形式:
- 第一种:使用script标签:<script type="text/x-template" id="myComponent"> 通过id来引用模板
- 第二种:使用template标签 :<template id="myComponent">通过id来引用模板。HTML5才有template标签,IE未实现此标签。
- 第三种:单文件组件( .vue格式文件)。适用与大型复杂的项目。
这个小demo 就使用简单的 script标签方式来写vue组件模板啦。
先看一下成品展示:
- 首先制作静态页:
制作动态页:
抽象出组件:抽象出三个组件 input组件,textarea组件,留言列表组件
input组件
编写模板
注册组件
使用组件
textarea 和留言列表组件:
注册组件:
使用组件
2.填充数据:
使用 v-model 指令在表单 <input> 及 <textarea> 元素上创建双向数据绑定。它会根据控件类型自动选取正确的方法来更新元素。
username 和 message 数据属性 保存输入的值.
v-model是语法糖,对inout事件的包装,相当于:
发布功能:
发布公能是 拿到输入的 昵称(username) 和 留言内容(message),填充到 留言板列表中。昵称和留言内容分别在 v-input 和 v-textarea组件中,而 按钮在 根组件中,与v-input和v-textarea为兄弟关系。 所以我们将 昵称 和留言 提取到 v-input v-textarea的父组件——根组件中。
通过 v-model指令,将昵称 和 留言内容,绑定到对应的子组件上去。
将v-model的值 绑定到 子组件中props中的 value属性上。父组件通过props向子组件传递数据。
在子组件中使用组件上v-model指令绑定的数据,input和 textarea标签需要使用,所以:
修改input标签元素,并删除v-input组件中的 data属性,这个不需要了:
将 props.value 绑定到 input元素的value属性上 :value 指向input元素的value属性。”value" 中的value指向 props中的value。input元素上 监听input事件。input事件调用父组件的input事件来更新值。
对比一下可以发现v-model指令使用在html标签上 和 使用在 组件之上是不一样的。当v-model指令 用在组件上的时候,跟用在DOM元素上的使用方式并不一样,在DOM元素上使用v-model时,Vue帮我们实现了语法糖。在组件上使用v-model,Vue帮我们实现了一半的语法糖,剩下一半需要我们自己实现 。
其实就是这样 :
1. 将根组件(根实例可以看作根组件)中的 message 绑定到 子组件v-input中的 props中的 value中 。
2. 将根组件中的 updataUsernameEvent 方法注册到 子组件中的 input事件上。
子组件v-input :
1.将v-input中的 props中的 value属性 绑定到 input标签中的 value属性上。
2.将v-input中的方法 childrenInputEvent 方法 注册 到inpu标签中的input事件上。
v-input中的childrenInputEvent 方法触发 父组件(根组件)注册到子组件上的input事件,调用updateUsernameEvent来修改 username属性的值
看下效果:
v-model指令语法糖的形式如下:
子组件:
子组件还可以简写成这样:
对比一下 可以发现 在组件上使用v-model指令时,Vue帮我们实现了一半的语法糖 :
v-model指令语法糖形式
没用使用v-model指令语法糖形式 :
子组件中 Vue没用帮我们实现语法糖,所以我们需要我们自己实现:
v-textarea组件同样如此。
点击发布按钮,将 username 与 message 存储到 留言列表中 :
做一些验证判断,将 username 与 message 存储到 留言列表中,并清空输入内容。将handleSend方法注册到 button标签元素的点击事件上。
使用push将数据插入数组中来触发视图更新。一定不要使用不能触发Vue视图更新的方式来修改更新数组!
Vue 不能检测以下变动的数组:
- 当你利用索引直接设置一个项时,例如:vm.items[indexOfItem] = newValue
- 当你修改数组的长度时,例如:vm.items.length = newLength
数组更新检测Vue官方文档 列表渲染 一节中有详细的介绍
渲染留言列表:
绑定留言列表 list到 留言板v-list组件上:
注册v-list组件:
使用v-for渲染留言板:
效果如下:
回复功能:
回复同样也是 将回复信息储存到留言列表中,所以将回复公能也放到 根组件中;
将handleReply方法注册到 v-list组件中的 reply事件上。
通过点击事件来触发 reply事件
点击回复按钮时候,我们需要触发input标签的焦点事件。我们怎么拿到 input标签元素呢?可以给 input标签做一个 标记:通过ref属性拿到所标记的元素或者组件实例:
通过 Vue的 $refs实例属性来访问 注册过 ref 特性 的所有 DOM 元素和组件实例。 如果在普通的 DOM 元素上使用,引用指向的就是 DOM 元素;如果用在子组件上,引用就指向组件实例
通过 Vue的$refs实例属性来访问 input标签元素,并触发其焦点事件。$refs实例属性 只能访问 当前组件作用域内的(组件html模板内部) ref标签,无法被外部访问,父组件也不可以。
无法访问
因此我们需要先拿到子组件,然后在通过子组件去拿着子组件中ref标记的html元素标签。
给子组件加一个 ref标记:
通过 refs拿到子组件实例,调用子组件中的方法:
子组件通过 refs 拿到作用域内的 ref标记,(input标签元素)并触发焦点事件
看下效果:
在增加一个删除留言的功能:
注册到子组件的 delete事件上:
通过点击事件触发 注册的 delete事件:
看下效果:
好了 一个简单的留言板功能我们实现完了。
注意:本文归作者所有,未经作者允许,不得转载