计算属性computed
计算属性是对现有的属性进行加工,要用的属性并不存在
计算属性的原理:底层借助Object.definepropoerty方法提供的getter和setter
get函数在第一次读取的时候会执行一次,在依赖的属性发生改变的时候会再次被调用
计算属性具有缓存性,效率更高,且计算属性最终会出现在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>
<!-- 引入vue框架 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2.7.10"></script>
</head>
<body>
<div id="root">
姓:<input type="text" v-model="fN"><br>
名:<input type="text" v-model="lN"><br>
全名:<span>{{fullName}}</span><br>
全名:<span>{{fullName}}</span><br>
全名:<span>{{fullName}}</span><br>
全名:<span>{{fullName}}</span><br>
全名:<span>{{fullName}}</span> <br>
全名:<span>{{fullName}}</span><br>
</div>
<script>
let vm = new Vue({
el: '#root',
data: {
fN: 'zhang',
lN: 'SAN',
},
// 计算属性:对现有的属性进行加工
computed: {
fullName: {
// 当有人读取fullname的时候,get就会被调用且返回值就作为fullname的值
// get 什么时候调用
// 答:当初次读取计算属性的时候会被调用,当所依赖的数据发生改变的时候调用
get() {
console.log('get被调用了');
// console.log(this);此处的this指向vm
return this.fN +'-'+ this.lN
},
// set的作用,当fullname的值被修改的时候调用
set(val) {
// console.log('set', val);
const arr =val.split('-')
this.fN=arr[0]
this.lN=arr[1]
}
}
// 简写方法
// fullName(){
// return this.fN +'-'+ this.lN
// }
}
})
</script>
<!-- -->
</body>
</html>
执行结果如下:
修改计算属性的值
监视属性watch
当被监视的属性发生变化时,回调函数自动调用,进行相关操作,监视属性必须存在才能监视,监视属性的两种写法:(1)new Vue的时候传入配置项watch。(2)通过vm.$watch监视
<!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>
<!-- 引入vue框架 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2.7.10"></script>
</head>
<body>
<div id="root">
<div>今天天气很{{info}}</div>
<button @click="change">切换</button>
</div>
<script>
let vm = new Vue({
el: '#root',
data: {
isHot: true
},
computed: {
info() {
return this.isHot ? '炎热' : '凉爽'
}
},
methods: {
change() {
this.isHot = !this.isHot
}
},
// watch: {
// info: {
// immediate: true,//初始化的时候调用handler,
// // 当isHot发生变化的时候handler函数调用
// handler(newValue, oldValue) {
// console.log('info被修改了', newValue, oldValue);
// }
// }
// }
})
vm.$watch('isHot',{
handler(newValue, oldValue) {
console.log('isHot被修改了', newValue, oldValue);
}
})
</script>
</body>
</html>
深度监视:(1)Vue中的watch默认不监视对象内部值的改变,只能监测到一层(a,b)(2)配置deep:true可以监测对象内部值改变(多层)(d)
vue自身可以监测对象内部值的改变,但是vue提供的watch默认是不可以的,使用watch的时候根据数据的具体结构决定是否采用深度监听
<!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>
<!-- 引入vue框架 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2.7.10"></script>
</head>
<body>
<div id="root">
<div>今天天气很{{info}}</div>
<button @click="change">切换</button>
<hr>
<div>a的值是{{number.a}}</div>
<button @click="number.a++">jiajia</button>
<hr>
<div>b的值是{{number.b}}</div>
<button @click="number.b++">jiajia</button>
</div>
<script>
let vm = new Vue({
el: '#root',
data: {
isHot: true,
number: {
a: 1,
b: 2
}
},
computed: {
info() {
return this.isHot ? '炎热' : '凉爽'
}
},
methods: {
change() {
this.isHot = !this.isHot
}
},
watch: {
isHot: {
// 当isHot发生变化的时候handler函数调用
handler(newValue, oldValue) {
console.log('isHot被修改了', newValue, oldValue);
}
},
// 监视多级结构中某个属性的变化
// 'number.a': {
// handler(newValue, oldValue) {
// console.log('a的值发生了变化', newValue, oldValue);
// }
// }
// 监视多级结构中所有属性的变化
number: {
deep:true,
handler(newValue, oldValue) {
console.log('number的值发生了变化', newValue, oldValue);
}
}
}
})
</script>
</body>
</html>
computed和watch的区别
1.computed能完成的功能watch都可以完成;
2.watch能完成的功能computed不一定能完成,例如watch可以进行异步操作
两个重要原则:(1)所有被vue管理的函数,最好写成普通函数,这样this的指向才是vm或组件实例(2)所有不被vue管理的函数(定时器的回调函数,Ajax的回调函数,promise的回调函数)最好写成箭头函数。
computed
(1)具有缓存性,页面重新渲染值不变化,计算属性会立即返回之前的计算结果,而不必再次执行函数
(2)计算属性计算某一个属性得变化,如果某一个值改变了,计算属性会见监听到进行返回
watch
(1) 监听值的变化,执行异步操作【axios请求】
(2)无缓存性,只有当当前值发生变化时才会执行/响应