computed
计算属性,类似于过滤器,对绑定到view的数据进行处理。
computed特性
- 是计算值
- 必须有
return
返回 - 应用:就是简化
tempalte
里面”{ { } }”计算和处理props
或$emit
的传值 - 具有缓存性,只有依赖数据发生改变,才会重新进行计算
computed
属性值会默认走缓存,页面重新渲染值不变化,计算属性是基于它们的响应式依赖进行缓存的,而不必再次执行函数- 不支持异步
- 不能在
data
中定义 - 变量不可被重复定义和赋值
- 如果
computed
属性值是函数,那么默认会走get
方法,函数的返回值就是属性的属性值;在computed
中的,属性都有一个get
和一个set
方法,当数据变化时,调用set
方法;
export default {
data(){
return{
firstName: 'Foo',
lastName: 'Bar'
}
},
computed: {
fullName:{
//回调函数 当需要读取当前属性值fullName时执行,根据相关数据计算并返回当前属性的值
get(){
return this.firstName + ' ' + this.lastName
},
//监视当前属性值fullName的变化,当属性值发生变化时执行,更新相关的属性数据
set(val){
//val就是fullName的最新属性值
console.log(val)
const names = val.split(' ');
console.log(names)
this.firstName = names[0];
this.lastName = names[1];
}
}
}
}
优点
当改变 data
变量值时,整个应用会重新渲染,vue 会被数据重新渲染到 dom
中。这时,如果我们使用 names ,随着渲染,方法也会被调用,而 computed
不会重新进行计算,从而性能开销比较小。当新的值需要大量计算才能得到,缓存的意义就非常大;
如果 computed
所依赖的数据发生改变时,计算属性才会重新计算,并进行缓存;当改变其他数据时,computed
属性并不会重新计算,从而提升性能;
当拿到的值需要进行处理时,就可以使用 computed
;
只有在
<template></template>
中或 函数中 使用computed
属性,computed
属性的计算方法才会执行。
使用场景
computed
适用一个数据被多个数据影响,例如购物车商品结算。
watch
watch是一个观察的动作
watch特性
- 是观察的动作
- 应用:监听
props
,$emit
或本组件data的值
执行异步操作 - 无缓存性,页面重新渲染时,值不变化也会执行,数据变化,也会直接触发相应的操作;
- 支持异步
- 监听数据必须是
data
中声明过或者父组件传递过来的props
中的数据。可以配合computed
使用 - 监听复杂数据类型需用深度监听
deep
为true immediate:true
页面首次加载的时候做一次监听
注:deep无法监听到数组的变动和对象的新增,参考vue数组变异,只有以响应式的方式触发才会被监听到。
注:当需要在数据变化时执行异步或开销较大的操作时,这个方式是最有用的,这是和 computed 最大的区别。
export default {
data(){
return{
firstName: 'Foo',
lastName: 'Bar',
fullName: 'Foo Bar'
}
},
watch: {
//监听firstName
firstName: function (val) {
this.fullName = val + ' ' + this.lastName
},
//监听lastName
lastName: function (val) {
this.fullName = this.firstName + ' ' + val
}
}
}
// 监听firstName和lastName的变化
深度监听虽然可以监听到对象的变化,但是无法监听到具体对象里面那个属性的变化。
oldVal
和newVal
值一样的原因是它们索引同一个对象/数组。Vue 不会保留修改之前值的副本。深度监听对应的函数名必须为
handler
,否则无效果,因为watcher里面对应的是对handler的调用。
监听对象单个属性
方法一:可以直接对用对象.属性的方法拿到属性
data(){
return{
'first':{
second:1
}
}
},
watch:{
first.second:function(newVal,oldVal){
console.log(newVal,oldVal);
}
}
方法二:用computed
作为中间件转化,因为computed
可以取到对应的属性值
data(){
return{
'first':{
second:1
}
}
},
computed:{
secondChange(){
return this.first.second
}
},
watch:{
secondChange(val){
console.log(val,'second属性值变化了')
}
},
注意事项
vue中如果直接对数组和对象的值进行修改是无法触发数据更新的,但是vue对数组的一些方法进行处理过就可以直接触发更新,例如,push、pop、shift、unshift、splice、sort、reverse这些。也可以用$set()
。vue对象的$set
可以直接修改数组和对象并触发响应更新。
使用场景
watch
适合一个数据影响多个数据,例如搜索框。