Vue2学习笔记(四):计算属性(computed)和监事属性(watch)
一、计算属性(computed)
computed属性中声明的变量会使用Object.defineProproty()类似的代理方式,拥有get和set两个方法。
get在(初次渲染页面和之后get中依赖的数据发生变化时被调用),内部有缓存机制,能够实现复用效率
而methods则是只要被访问同一次就读取内存一次。
<!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>姓名案例</title>
<!-- 下载到本地引用 -->
<script type="text/javascript" src="./js/vue2.js"></script>
</head>
<body>
<div id="root">
<input type="text" v-model="lastName"><br/>
<input type="text" v-model="firstName"><br/>
姓名_插值语法:<span>{{lastName}} - {{firstName}}</span><br/>
<!-- 在插值语法中的函数不能省略 () -->
姓名_methods属性:<span>{{joint()}}</span><br/>
姓名_computed属性:<span>{{fullName}}</span><br/>
</div>
<script type="text/javascript">
Vue.config.productionTip = false;
const vm = new Vue({
el: '#root',
data(){
return{
lastName:'张',
firstName: '三',
}
},
methods: {
joint(){
return this.lastName + ' - ' + this.firstName;
}
},
computed: {
// // 与Object.getProperty()类似
// // 在computed属性中声明一个fullName
// fullName: {
// // get在(初次渲染页面和之后get中依赖的数据发生变化时被调用),内部有缓存机制,能够实现复用效率
// // 而methods则是只要被访问同一次就读取内存一次
// get(){
// return this.lastName + ' - ' + this.firstName;
// },
// // set当fullName被修改时调用
// set(value){
// const arr = value.split('-');
// this.lastName = arr[0];
// this.firstName = arr[1];
// }
// }
// computed的简写,注意只有不需要使用set时才能使用简写形式
fullName(){
return this.lastName + ' - ' + this.firstName;
}
},
})
</script>
</body>
</html>
注意当只需要get方法时才可以只用上述代码中的简写形式。
二、监视属性(watch)
1.一般监视
vue配置中还有一个属性watch,可以用来监视data、compute中配置的属性,一旦发生了变化就会默认调用其中的handler()方法,并且该方法有两个参数分别为新的值和旧的值。
代码示例:
<!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>天气案例</title>
<!-- 下载到本地引用 -->
<script type="text/javascript" src="./js/vue2.js"></script>
</head>
<body>
<div id="root">
<h2>今天是{{weather}}</h2>
<button @click="changeWeather">点我切换天气</button>
</div>
<script type="text/javascript">
Vue.config.productionTip = false;
const vm = new Vue({
el: '#root',
data(){
return{
isClear: true
}
},
methods: {
changeWeather(){
this.isClear = !this.isClear;
}
},
computed: {
weather(){
return this.isClear ? '晴天' : '阴天';
}
},
watch: {
isClear:{
// 被监视对象初始化时也调用一下handler() 由于初始化时没有旧值所以为 undefined
immediate: true,
// 当被监视对象发生改变时被调用 有两个参数分别为:新的值和旧的值
handler(newValue, oldValue){
console.log(newValue, oldValue);
}
}
},
});
// 也可以在外部挂载监视
// vm.$watch('isClear', {
// immediate: true,
// handler(newValue, oldValue){
// console.log(newValue, oldValue);
// }
// });
</script>
</body>
</html>
我们还可以通过vue.$watch(‘propertyName’,{ … })的形式在创建了vue实例后添加对某个属性的监视。
2.深度监视
所谓深度监视就是监视的对象是可能是一个对象中某个属性或对象的值
例如data中的对象
number{
a:1,
b:1
}
想要监视对象number中的属性a不能在watch中直接使用number.a: {}这种形式,而是用引号将其引起来:‘number.a’: {}
对于多级结构的对象,如果想要检测对象内部任意一个属性是否发生了变化就要用到deep属性。
代码示例:
<!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>深度监视</title>
<!-- 下载到本地引用 -->
<script type="text/javascript" src="./js/vue2.js"></script>
</head>
<body>
<div id="root">
<h2>你的年龄是:{{people.info.age}}</h2>
<button @click="people.info.age++">点我变的更成熟</button>
<button @click="people.info.age--">点我变的更年轻</button>
</div>
<script type="text/javascript">
Vue.config.productionTip = false;
const vm = new Vue({
el: '#root',
data(){
return{
people:{
info:{
age: 18,
phonenumber: '911'
},
name: '张三'
}
}
},
watch: {
// //一般来说我们的属性都应该用引号引起来,这才是标准的写法,先前的写法都是一种简写的形式
// 'people.age':{
// handler(newValue, oldValue){
// console.log('年龄被改变了');
// }
// }
// 配置deep属性为true开启深度监视,检测多级结构对象内部数据是否发生了改变
people:{
// 默认不检测对象内部的值的改变
deep: true,
handler(newValue, oldValue){
console.log('年龄被改变了');
}
},
// 如果不使用其余的配置就可以直接简写为如下形式
// people(newValue, oldValue){
// console.log('年龄被改变了');
// }
},
});
</script>
</body>
</html>
上述代码包含了watch中监视的简写形式。
computed能实现的功能,watch都能实现;watch能实现的computed不一定能实现。
ps:箭头函数没有自己的this指针,它会继承上一级结构的this指针
三、关于vue中this指针的一些细节
例子如下:
people:{
// 默认不检测对象内部的值的改变
deep: true,
handler(newValue, oldValue){
// 不能使用function() 否则this指针就会指向Window
setTimeout(() => {
// 箭头函数的没有自己的this指针,而去继承了上一级handler的指针也就是vue实例
console.log(this);
console.log('年龄被改变了');
}, 2000);
}
},
这是一个被watch检测的一个属性,如果想要在handler中使用不被vue管理的函数最好将 function(){} 改写为 => 箭头函数。
这样this指针就会继承上一级结构的this指针也就是vue实例。