计算属性(computed)
定义:
要用的属性不存在,要通过已有属性计算得来
原理:
底层接住了object.defineproperty方法提供的getter和setter
get函数什么时候执行
- 初次读取时会执行一次
- 当依赖的数据发生改变时会被再次调用
优势:
与methods实现相比,内部有缓存机制(复用),效率更高,调试方便
注意:
- 计算属性最终会出现在vm上,直接读取使用即可
- 如果计算属性要被修改,那必须直接写set函数去响应修改,且set中要引起计算式以来的数据发生改变
接下来使用计算属性来完成一个姓名案例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="js/vue.js"></script>
</head>
<body>
<div id="root">
姓:<input type="text" v-model="firstname"><br>
名:<input type="text" v-model="lastname"><br>
全名:<span>{{fullname}}</span>
</div>
<script>
const vm = new Vue({
el: '#root',
data: {
firstname: '张',
lastname: '三'
},
computed: {
fullname: {
get() {
console.log('get');
return this.firstname + '-' + this.lastname;
},
set(value) {
console.log(value);
const arr = value.split('-');
this.firstname = arr[0];
this.lastname = arr[1];
}
}
// //简写形式
// fullname() {
// console.log('get');
// return this.firstname + '-' + this.lastname;
// }
}
})
</script>
</body>
</html>
简写形式
只考虑读取不考虑修改的时候使用
简写形式
fullname() {
console.log('get');
return this.firstname + '-' + this.lastname;
}
监视属性(watch)
定义:
当被监视的属性变化时,回调函数自动调用,进行相关操作
注意:
监视的属性必须存在,才能进行监视
监视的两种写法:
new vue 时传入watch配置
watch: {
isHot: {
immediate: true,//初始化时让handler调用一下
//当isHot发生改变时调用
handler(newValue, oldValue) {
console.log('isHot被修改了', newValue, oldValue);
}
}
}
通过vm.$watch监视
vm.$watch('isHot', {
immediate: true,//初始化时让handler调用一下
//当isHot发生改变时调用
handler(newValue, oldValue) {
console.log('isHot被修改了', newValue, oldValue);
}
})
深度监视
- Vue中的watch默认不监测对象内部值的改变(一层)
- 配置deep:true可以检测对象内部值改变(多层)
watch: {
numbers: {
deep: true,
// immediate: true,//初始化时让handler调用一下
//当isHot发生改变时调用
handler(newValue, oldValue) {
console.log('isHot被修改了', newValue, oldValue);
}
}
}
备注
- Vue自身可以监测对象内部值的改变,但Vue提供的watch默认不可以
- 使用watch时根据数据的具体结构,决定是否采用深度监视
其中 handler(newValue, oldValue) { },newValue是改变前的值,oldValue是改变后的值
使用监视属性来完成天气案例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="js/vue.js"></script>
</head>
<body>
<div id="root">
<h1>今天天气很{{info}}</h1>
<button @click="change">切换天气</button>
<!-- <button @click="isHot = !isHot">切换天气</button> -->
</div>
<script>
const vm = new Vue({
el: '#root',
data: {
isHot: true
},
computed: {
info() {
return this.isHot ? '炎热' : '凉爽';
}
},
methods: {
change() {
this.isHot = !this.isHot;
}
},
//第一种写法
watch: {
isHot: {
immediate: true,//初始化时让handler调用一下
//当isHot发生改变时调用
handler(newValue, oldValue) {
console.log('isHot被修改了', newValue, oldValue);
}
}
//在只使用handler属性的情况下可以简写
// isHot(newValue, oldValue) {
// console.log('isHot被修改了', newValue, oldValue);
// }
}
})
//第二种写法
// vm.$watch('isHot', {
// immediate: true,//初始化时让handler调用一下
// //当isHot发生改变时调用
// handler(newValue, oldValue) {
// console.log('isHot被修改了', newValue, oldValue);
// }
// })
//简写方式
// vm.$watch('isHot', function (newValue, oldValue) {
// console.log('isHot被修改了', newValue, oldValue);
// })
</script>
</body>
</html>
简写:在只使用handler属性的情况下可以简写
computed和watch之间的区别
- computed能完成的功能,watch都可以完成
- watch能完成的功能,computed不一定能完成
- 例如:watch可以进行异步
两个重要的小原则
所被Vue管理的函数,最好写成普通函数,这样this的指向才是vm或组件实例对象
所有不被Vue管理的函数(定时器的回调函数,ajax的回调函数,promise的回调函数),最好写成箭头函数,这样this的指向才是vm或组件实例对象