computed
computed是计算属性的
它会根据所依赖的数据动态显示新的计算结果,计算的结果会被缓存起来
computed的值在getter执行后是会被缓存的。如果所依赖的数据发生改变时候,就会重新调用getter来计算最新的结果。
根据 Vue 文档例子来理解computed的使用
computed设计的初衷是为了使模板中的逻辑运算更简单
<body>
<div id="app">
{{ msg.split('').reverse().join('') }}
</div>
<script type="text/javascript">
new Vue({
el: '#app',
data: {
msg: 'hello'
}
});
</script>
</body>
我们在vue模板中会对该数据值进行反转操作后输出数据, 因此在页面上就会显示 olleh
如果页面中的运算比这个还更复杂的话, 这个时候我们可以使用computed来进行计算属性值。把上面的代码改写成下面如下代码:
<body>
<div id="app">
<p>原来的数据: {{ msg }}</p>
<p>反转后的数据为: {{ reversedMsg }}</p>
</div>
<script type="text/javascript">
var vm = new Vue({
el: '#app',
data: {
msg: 'hello'
},
computed: {
reversedMsg() {
// this 指向 vm 实例
return this.msg.split('').reverse().join('')
}
}
});
</script>
</body>
如上代码, 我们在computed中声明了一个计算属性reversedMsg。我们提供的reversedMsg函数, 将用作属性 vm.reversedMsg的getter函数
我们也可以打开控制台, 当我们修改 vm.msg 的值后, vm.reversedMsg 的值也会发生改变,如下控制台打印的信息可知:
vm.msg = '111'
'111'
vm.reversedMsg
'111'
我们的vm.reversedMsg的值依赖于vm.msg的值,当vm.msg的值发生改变时, vm.reversedMsg的值也会得到更新
computed应用场景
-
适用于一些重复使用数据或复杂及费时的运算。我们可以把它放入
computed中进行计算, 然后会在computed中缓存起来, 下次就可以直接获取了。 -
如果我们需要的数据依赖于其他的数据的话, 我们可以把该数据设计为
computed中。
watch的用法
watch用于侦听data的数据。
当data数据发生变化,执行函数。在函数中会传入newVal和oldVal两个参数
watch属性可以是字符串、函数、对象、数组
拥有deep,immediate两属性
示例
new Vue({
data: {
n: 0,
obj: {
a: "a"
}
},
template: `
<div>
<button @click="n += 1">n+1</button>
<button @click="obj.a += 'hi'">obj.a + 'hi'</button>
<button @click="obj = {a:'a'}">obj = 新对象</button>
</div>
`,
watch: {
n() {
console.log("n 变了");
},
obj() {
console.log("obj 变了");
},
"obj.a": function() {
console.log("obj.a 变了");
}
}
}).$mount("#app");
点击n+1 : 打印出“n 变了”
点击obj.a + 'hi' : 打印出“obj.a 变了”,不打印"obj 变了"
不点击obj.a + 'hi' , 点击obj = 新对象: 打印出"obj 变了",不打印"obj 变了"
说明watch的监听方式是:简单数据类型看值,复杂数据类型(对象)看地址
,但可以通过deep监听obj内部obj.a的变化
使用deep属性
watch: {
n() {
console.log("n 变了")
},
obj() {
console.log("obj 变了")
deep: ture // 可以监听到obj对象的所有内部属性
},
"obj.a": function() {
console.log("obj.a 变了")
}
}
点击obj.a + 'hi' : 打印出“obj.a 变了”和 "obj 变了"
当deep:true 会监听到obj对象的所有内部属性,默认值为false
immediate属性
new Vue({
data: {
firstName: 'Jacky',
lastName: 'Lee',
fullName: ''
},
watch: {
firstName: {
handler: 'change'
}
},
template: `
<div>
{{fullName}}
<button @click="firstName='John'">改名字</button>
</div>
`,
methods: {
change() {
this.fullName = this.firstName + ' ' + this.lastName
}
}
}).$mount("#app");
运行上面代码,页面啥也没有,然后点击“改名字”,页面依然显示 John Lee,并未发生变化
这因为watch不会监听第一次变化
改造一下
watch: {
firstName: {
handler: 'change',
immediate: ture
}
}
当 immediate:true 时,回调函数会在监听开始后立刻执行,可以监听到到第一次变化。
总结:
computed是用来计算一个值的,使用时不需要加括号,可以直接当属性使用。computed拥有依赖缓存特性,如果依赖值不变,computed不会重新计算
watch是用来监听的,有两个选项,immediate 和 deep,当 immediate: true 时,表示会在第一次运行是执行这个函数,当 deep:true 时,如果监听一个对象,会同时监听其内部属性。watch没有依赖缓存特性。