基本操作(中)
本章节主要介绍:vue的条件渲染、列表渲染,计算属性和侦听器
条件渲染和列表渲染
条件渲染主要使用到了 v-if 指令,列表渲染主要使用了 v-for 指令。
下面介绍 v-if 、 v-for 和 <template> 标签 指令的使用:
v-if
作用:控制元素的是否渲染。True为渲染 false不渲染,如下基本操作:
Demo:
<div id="app"> <!-- 如果 seen 为true就显示 --> <div v-if="seen" class="box"></div> <!-- 这里用一个button控制 seen 的值 --> <button @click="handleClick">点击按钮: seen 值取反</button> </div> <script src="node_modules/vue/dist/vue.js"></script> <script> new Vue({ el : '#app' , data : { seen : false }, methods : { handleClick : function () { console.log("进入事件处理"); this.seen = !this.seen; } } }); </script> </body> <style type="text/css"> .box { display : block; width : 20px; height: 20px; background-color: blue; } </style>
v-for
作用:进行列表渲染时,可以使用 v-for 进行遍历渲染,如下基本操作:
Demo:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>vue-事件绑定</title> </head> <body> <div id="app"> <ul> <li v-for="item in todos"> <a href="">{{ item.title }} </a> </li> </ul> </template> </div> <script src="node_modules/vue/dist/vue.js"></script> <script> const todos = [ { id: 1, title: '吃饭', done: true }, { id: 2, title: '睡觉', done: false }, { id: 3, title: '打球', done: true } ] // 得到 Vue 实例 const app = new Vue({ el: '#app', data: { todos : todos }, methods:{ } }) </script> </body> </html>
Tips:这里for循环既可使用 of、也可以使用in。但vue更推荐使用of,因为es6中有一种for of循环,这种循环遍历方法更加通用,也更加接近es6语法。
实际操作中 v-if 和 v-for 常常会结合 <template> 标签使用,用以控制显示和渲染。
template标签
- 什么是 <template> 标签?
■ vue提供的特殊标签,Html不会识别这个标签,但是vue编译时会识别这个标签。
■ 使用场景:如果你需要将条件控制渲染多个元素,而又不想额外添加 <div> ,这就可以把他们都放到一个template标签中,Vue会识别它,并且在渲染结果中不会有 <template> 标签。
■ 我们常常使用 <template> 结合 v-if 和 v-for 来控制多个元素的显示。
结合 v-if 和 v-for 使用如下Demo:
运行效果:
计算属性和侦听器
侦听器
Vue 提供了一种更通用的方式来观察和响应 Vue 实例上的数据变动:侦听属性—watch
简单理解:侦听属性就是对某个属性进行侦听,如果改变了则会触发相应的事件处理。
Demo:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>vue-事件绑定</title> </head> <body> <div id="app"> <p>这里用一个输入框双向数据绑定来观察侦听器是否起作用</p> <input type="text" v-model="str1"> </div> <script src="node_modules/vue/dist/vue.js"></script> <script> // 当需要对某个属性做onchange事件,时使用侦听器更加方便 // 得到 Vue 实例 const app = new Vue({ el: '#app', data: { str1 : 'a' }, watch: { // 监听str1属性,当str1属性改变时会执行这个方法 str1 (val, oldVal) { console.log(`str1改变了,变成:${val} 原值:${oldVal}`); } } }) </script> </body> </html>
运行效果:
计算属性
为什么会需要计算属性?
如果现在 vue 中 data 有两个对象 str1 和 str2 ,然后你希望得到这两个 str 的拼接结果,作为 vue 中的数据用于显示,并且会随着 str1 和 str2 改变而改变,你会怎么做?
请看下面 demo :
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>vue-事件绑定</title> </head> <body> <div id="app"> <!-- 这里显示str1和str2拼接的结果 --> <h1>{{ merge }}</h1> <!-- 设置两个文本框可以手动改变str1和str2的值 --> <input type="text" v-model="str1"> <input type="text" v-model="str2"> </div> <script src="node_modules/vue/dist/vue.js"></script> <script> // 为什么需要计算属性? // 现在有 str1 和 str2,如果你想要得到 str1 和 str2的拼接结果,并且跟随 str1 和 str2 的改变而改变,你会怎么做? // 第一反应:在 data 中添加一个合并属性,如:merge:this.str1 + this.str2 // 错误 // 因为在 data 属性中,this 指向 window 这时是无法通过 this.str1 或 this.str2 来获取到 str1 和 str2 的 // 而直接写 merge : str1 + str2 更是无法取到的。 // 得到 Vue 实例 const app = new Vue({ el: '#app', data: { str1 : 'a', str2 : 'b' }, computed: { // 计算属性自动监听了内部依赖的响应式成员 // 当它依赖的响应式成员发生变化,则它自己会进行重新计算调用 merge (event) { // 这里使用 es6 提供的反引号字符串拼接的方法,不会的小伙伴可以参考 es6反引号 // computed 内的属性,既是属性又是方法,里面的 this 指向 vue 实例本身 return `${this.str1} -- ${this.str2}`; } } }) </script> </body> </html>
实现效果:
当 str1 或 str2 改变时,计算属性merge都会随着改变。
计算属性是基于它们的依赖进行缓存的。计算属性只有在它的相关依赖发生改变时才会重新求值。即意味着,如果取计算属性时,依赖属性没有改变,计算属性会立即返回之前的计算结果,而不必再次执行函数。
简单理解:计算属性是方法,但是你可以像绑定属性一样把它当作属性进行绑定。
当然,计算属性的操作也可以用侦听器完成,但是一般用计算属性完成的操作,改成侦听器完成的操作会麻烦很多。
计算属性和侦听器对比:
下面用 merge 是 str1 和 str2 拼接结果的两种实现来对比一下:
<div id="app"> <!-- 这里显示str1和str2拼接的结果 --> <h1>{{ merge }}</h1> <!-- 设置两个文本框可以手动改变str1和str2的值 --> <input type="text" v-model="str1"> <input type="text" v-model="str2"> </div> <script> // 得到 Vue 实例 const app = new Vue({ el: '#app', data: { str1 : 'a', str2 : 'b' }, computed: { // 使用计算属性就一个计算属性就能解决 merge (event) { return `${this.str1} -- ${this.str2}` } } }) </script>
<div id="app"> <!-- 这里显示str1和str2拼接的结果 --> <h1>{{ merge }}</h1> <!-- 设置两个文本框可以手动改变str1和str2的值 --> <input type="text" v-model="str1"> <input type="text" v-model="str2"> </div> <script> // 得到 Vue 实例 const app = new Vue({ el: '#app', data: { str1 : 'a', str2 : 'b', merge : '' }, watch: { // 使用侦听器不仅要加一个响应式成员属性,还需要多个侦听方法 str1 (event) { this.merge = `${this.str1} -- ${this.str2}` }, str2 (event) { this.merge = `${this.str1} -- ${this.str2}` } } }) </script>
自定义计算属性的get和set:
计算属性默认方法为get方法,就如我们上面几个计算属性 demo 中定义实际上都是定义计算属性的 get 方法,但如果有需要的话还能设置其set方法。
Demo:
计算属性默认只有 getter ,不过在需要时你也可以提供一个 setter :
// ... computed: { fullName: { // getter get: function () { return this.firstName + ' ' + this.lastName }, // setter set: function (newValue) { var names = newValue.split(' ') this.firstName = names[0] this.lastName = names[names.length - 1] } } } // ...
现在再运行 vm.fullName = 'John Doe'
时,setter 会被调用,vm.firstName
和 vm.lastName
也会相应地被更新。
使用建议:
- 计算属性用于需要在模板中绑定输出值。
- 而watch侦听器则用于需要根据数据的改变,从而定制特殊功能业务处理.
■ Watch只是监视,不返回数据,而且只能侦听自己的data成员
■ 不适用于模板绑定