Vue2-computed和watch区别
1. computed属性
定义:要用的属性不存在,需要通过已有属性计算得来。
原理:底层借助了Objcet.defineproperty()方法提供的getter和setter方法。getter方法用于获取值,而setter方法用于指定值。
理解:相当于一个已知的公式,公式所有的数值都是已知的,但需要我们计算,同时数值可能是变化的,所以需要进行更新,并把计算的结果返回,并采用指定属性接收,如果数值不变,则不会使用该公式(此处的公式,是指computed属性中的一个方法)。
- 完整写法
<body>
<div id="root">
姓:<input type="text" v-model="firstName"><br>
名:<input type="text" v-model="lastName"><br>
<h2>计算属性</h2>
姓名:{{fullName}}<br>
<button @click="changeFullName">点我修改fullName</button>
</div>
<script>
new Vue({
el:'#root',
data:{
firstName:'张',
lastName:'三'
},
methods: {
changeFullName(){
this.fullName='欧阳-修'
}
},
computed:{
fullName:{
get(){
return this.firstName+'-'+this.lastName
},
set(value){
const arr = value.split('-')
this.firstName = arr[0]
this.lastName = arr[1]
}
}
},
})
</script>
</body>
- 简写
如果不考虑修改计算属性的值,可以采取以下简写方式:
<body>
<div id="root">
...
</div>
<script>
new Vue({
el:'#root',
data:{
firstName:'张',
lastName:'三'
},
methods: {
changeFullName(){
this.fullName='欧阳-修'
}
},
// 简写
computed:{
fullName(){
return this.firstName + '-' + this.lastName
}
}
})
</script>
</body>
- 如果需要修改计算属性的值,但采用简写方式则会报错,显示定义了getter方法,但没有setter方法
1.1 computed与methods的区别
- computed内部有缓存机制,当依赖数据不变时,直接返回缓存的值,不会重新调用,可以进行复用,而methods只要被调用就会执行。
- 最终可以实现同一种效果
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="./01/js/vue.js"></script>
</head>
<body>
<div id="root">
<h2>计算属性</h2>
姓名:{{fullName}}<br>
姓名:{{fullName}}<br>
姓名:{{fullName}}<br>
姓名:{{fullName}}<br>
姓名:{{fullName}}<br>
<hr>
<h2>methods</h2>
姓名:{{getFullName()}}<br>
姓名:{{getFullName()}}<br>
姓名:{{getFullName()}}<br>
姓名:{{getFullName()}}<br>
姓名:{{getFullName()}}<br>
</div>
<script>
new Vue({
el:'#root',
data:{
firstName:'张',
lastName:'三'
},
methods: {
getFullName(){
console.log('getFullName方法被调用了');
return this.firstName + '-' + this.lastName
}
},
// 简写
computed:{
fullName(){
console.log('fullName方法被调用了');
return this.firstName + '-' + this.lastName
}
}
})
</script>
</body>
</html>
分别引用同一数据5次,运行结果显示:
2. watch属性
定义:监视一个或多个数据的变化,并在数据发生变化时执行特定的逻辑。
原理:基于Vue.js的响应式系统来实现。Vue.js的响应式系统通过使用Object.defineProperty或Proxy来劫持对象的属性访问,从而实现对数据的监听和响应。
理解:相当于你买了一只股票,你需要一直监视这个股票的涨和跌,你可以获取到股票这次的收益,和上次的收益。当股票发生变化时,就会调用监听,并更新值。
2.1 监听简单数据
- 完整写法
<body>
<div id="root">
<input type="text" v-model="infor">
</div>
<script>
new Vue({
el:'#root',
data:{
infor:'我爱学习'
},
watch:{
// 监视的数据
infor:{
deep: false, // 是否深度监听
immediate: true, // 是否在组件创建时立即执行回调函数
// 监听函数,当数据发生变化时执行
handler(newValue,oldValue){
console.log('infor被修改了',newValue,oldValue);
}
}
}
})
</script>
</body>
- 简写
<body>
<div id="root">
<input type="text" v-model="infor">
</div>
<script>
new Vue({
el:'#root',
data:{
infor:'我爱学习'
},
watch:{
infor(newValue,oldValue){
console.log('infor被修改了',newValue,oldValue);
},
}
})
</script>
</body>
2.1 监听对象
如果不开启深度监视,修改对象的属性值,则不会调用watch属性监听的函数,如果要引起watch属性的监视则需要设置deep: true
<body>
<div id="root">
<input type="text" v-model="infor.name">
</div>
<script>
new Vue({
el:'#root',
data:{
infor:{
name:'张三',
age:20
}
},
watch:{
// 监视的数据
infor:{
deep: true, // 是否深度监听
immediate: true, // 是否在组件创建时立即执行回调函数
// 监听函数,当数据发生变化时执行
handler(newValue,oldValue){
console.log('infor被修改了',newValue,oldValue);
}
},
}
})
</script>
</body>
2.2 watch与methods的区别
相同点:
- 都没有缓存机制
- 最终可以实现同一种效果
不同点:
watch是基于数据变化来触发的,当所监听的数据发生变化时,相应的监听函数会被调用。而methods是在特定的事件或条件触发下才会执行
2.2 computed与watch的区别
- 当依赖数据变化时,computed返回值,需要属性接收,watch直接修改当前监听的属性值。
- computed内部有缓存机制,依赖的数据发生改变才会重新计算,watch内部有缓存机制,只要监听的数据变化就会触发相应操作
- computed能实现的,watch也可以,但computed性能更好。watch能实现的,computed不一定能,例如:watch可以进行异步操作。