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.reversedMsg
的值依赖于vm.msg
的值,当vm.msg
的值发生改变时, vm.reversedMsg
的值也会得到更新
computed应用场景
1. 适用于一些重复使用数据或复杂及费时的运算。我们可以把它放入computed
中进行计算, 然后会在computed
中缓存起来, 下次就可以直接获取了。
2. 如果我们需要的数据依赖于其他的数据的话, 我们可以把该数据设计为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的监听方式是:简单数据类型看值,复杂数据类型(对象)看地址
那我想通过监听obj
也能obj.a
变化可以吗?
答:请使用deep
使用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没有依赖缓存特性。