vue- 计算属性
(1) 基础例子
有的时候我们需要在模板中使用数据a,这个时候就需要用到表达式,但是有的地方我们需要对a数据进行一些简单的处理后才能使用,那么我们就会在表达式中写一些js逻辑运算比如现在我们要实现num值2倍的计算,
<div id="app">
<p><button @click="num++">点击</button></p>
<p>num: {{num}}</p>
<p>num*2: {{num*2}}</p>
<p><input type="text" v-model='msg'></p>
</div>
缺点:如果在很多地方都用到这个计算的话,后期修改起来就会比较麻烦
(2)封装函数的方法
我们可以把多次操作的内容封装成一个函数进行调用
<p>方法:{{doubleNum()}}</p>
var vm = new Vue({
el:"#app",
data:{
num:1,
},
methods:{
doubleNum(){
return this.num*2
}
}
})
但是这个时候,只要vm中有数据变化,这个变化的数据可能和我们关注的数据无关,但是vm都会重新渲染模板,这个时候表达式中的方法就会重新执行,大大的影响性能
(3)通过watch监听器实现此功能
watch可以监听现有的数据的改变,然后当现有数据发生改变了,内部就会实现一些业务逻辑
<div id="app">
<p><button @click="num++">点击</button></p>
<p>watchNum: {{watchNum}}</p>
</div>
<script>
var vm = new Vue({
el:"#app",
data:{
num:1,
watchNum:''
},
watch:{
//监听num值的改变,一旦num发生变化了,就让watchNum变成更改后的新值的2倍
//在vm实例中设置watch属性,在里面通过键值对来设置一些监听,键名为数据名,值可以是一个函 数,这个函数在数据改变之后才会执行,两个参数分别是更改前的值和更改后的值
// num:function(newValue,oldValue){
// this.watchNum = newValue*2
// }
num:{
// 值还可以是一个方法名字,当数据改变的时候这个方法会执行
//当数据为object的时候,object的键值对改变不会被监听到(数组的push等方法可以),这个时候需要设置深度监听:
immediate:true, //代表初始化的时候也让其执行一次
handler:function(newValue){
this.watchNum = newValue*2
}
}
}
})
</script>
(4)computed计算属性来实现
计算属性的写法是一个函数,但是在上面调用的时候千万不能加括号调用。
会根据现有数据生成一个新的数据,并且两者产生关联,建立永久性缓存。
并且当无关数据发生改变的时候,计算属性内部不会重新计算,而是直接从缓存里面取数据即可
<div id="app">
<p><button @click="num++">点击</button></p>
<p>computedNum: {{computedNum}}</p>
</div>
<script>
var vm = new Vue({
el:"#app",
data:{
num:1,
},
computed:{
computedNum(){
console.log("计算属性...")
return this.num*2
}
}
})
</script>
(5)computed VS watch区别
- watch的监听只是单个的监听,每次监听只能监听一个变量的修改,不能同时监听多个变量的同时更改。
而计算属性computed可以依赖多个数据的变化(并且只跟它所依赖项进行关联)
-
当需要在数据变化时执行异步或开销较大的操作时,只能选择采用watch去实现。
-
计算属性就是在实例配置项中通过computed来为vm设置一个新的数据,而这个新数据会拥有一个依赖(一条已经存在的数据),当依赖发生变化的时候,新数据也会发生变化
-
与方法的方式相比,它性能更高,计算属性是基于它们的依赖进行缓存的。计算属性只有在它的相关依赖发生改变时才会重新求值。相比之下,每当触发重新渲染时,调用方法将总会再次执行函数。
-
与watch相比,写起来简单,逻辑性更清晰,watch一般多用于,根据数据的变化而执行某些动作,而至于这些动作是在干什么其实无所谓,而计算属性更有针对性,根据数据变化而更改另一个数据
-
计算属性也拥有getter和setter,默认写的是getter,设置setter可以当此计算属性数据更改的时候去做其他的一些事情,相当于watch这个计算属性
<div id="app"> <p>{{fullName}}</p> <input type="text" v-model="fullName"> </div> <script> new Vue({ el:"#app", data:{ firstName:"zhang", lastName:"san" }, computed:{ fullName: { get: function () { return this.firstName + ' ' + this.lastName }, set: function (newValue) { var names = newValue.split(' ') this.firstName = names[0] this.lastName = names[names.length - 1] } } } }) </script>