Vue中computed与watch


computed (计算属性)

  1. 属性的结果会被缓存,当computed中的函数所依赖的属性没有发生改变的时候,那么调用当前函数的时候结果会从缓存中读取,除非依赖的响应式属性变化时才会重新计算;
  2. 不支持异步,当computed内有异步操作时无效,无法监听数据的变化;
  3. computed中的函数必须用return返回最终的结果。computed更高效,优先使用;
  4. 当一个属性受多个属性影响的时候,一般用computed(购物车商品结算功能);
  5. 如果computed属性属性值是函数,那么默认会走get方法;函数的返回值就是属性的属性值;在computed中的,属性都有一个get和一个set方法,当数据变化时,调用set方法;
<template>
	<div>
		<p>{{fullName}}</p>
	</div>
</template>

<script type="text/ecmascript-6">
export default {
	name: "",
	data() {
		return {
			firstName: '张',
			lastName: '三'
		}
	},
	computed: {
		fullName() {
			return this.firstName + ' ' + this.lastName
		}
	}
}
</script>

getter 与 setter

通过 getter\setter 实现对属性数据的显示和监视,计算属性存在缓存,多次读取只执行一次getter计算

<template>
	<div>
		<p>{{fullName}}</p>
	</div>
</template>

<script type="text/ecmascript-6">
export default {
	name: "",
	data() {
		return {
			firstName: '张',
			lastName: '三'
		}
	},
	computed: {
		fullName: {
		    // getter  对属性数据的显示
			get() {// 回调函数 当需要读取当前属性值时执行,根据相关数据计算并返回当前属性的值
				return this.firstName + ' ' + this.lastName
			},
		    // setter  对属性数据的监听
			set(val) { // 监听当前属性值的变化,当属性值发生变化时执行,更新相关的属性数据
				// val就是fullName的最新属性值
				console.log(val)
				const names = val.split(' ');
				console.log(names)
				this.firstName = names[0];
				this.lastName = names[1];
			}
		}
	}
}
</script>

watch(监听属性)

  1. 不支持缓存,数据变,直接会触发相应的操作;
  2. 支持异步
  3. 监听的函数接收两个参数,第一个参数是最新的值(newVal);第二个参数是输入之前的值(oldVal);
  4. 当一条数据影响多条数据的时候,一般使用watch(搜索数据);
  5. 监听数据必须是data中声明过或者父组件传递过来的props中的数据,当数据变化时,触发其他操作,函数有两个参数,
      immediate:组件加载立即触发回调函数执行,
      deep: 深度监听,为了发现对象内部值的变化,复杂类型的数据时使用,例如数组中的对象内容的改变,注意监听数组的变动不需要这么做。注意:deep无法监听到数组的变动和对象的新增,参考vue数组变异,只有以响应式的方式触发才会被监听到。
<template>
	<div>
		<input type="text" v-model="name">
	</div>
</template>

<script type="text/ecmascript-6">
export default {
	name: "",
	data() {
		return {
			name: '张三'
		}
	},
	watch: {
		name(newVal, oldVal) {
			console.log(newVal, oldVal);
		}
	}
}
</script>

immediate(立即监听)

<template>
	<div>
		<p>FullName: {{fullName}}</p>
		<p>FirstName: <input type="text" v-model="firstName"></p>
	</div>
</template>

<script type="text/ecmascript-6">
export default {
	name: "",
	data() {
		return {
			firstName: '张',
			lastName: '三',
			fullName: ''
		}
	},
	watch: {
		firstName: {
			handler(newVal, oldVal) {
				this.fullName = newVal + this.lastName;
			},
			// 代表在wacth里声明了name这个方法之后立即先去执行handler方法
			immediate: true
		}
	}
}
</script>

deep(深度监听)

由于 Vue 不能检测到对象属性的添加或删除,这时候deep属性就派上用场了!

<template>
	<div>
		<p>obj.a: {{obj.a}}</p>
		<p>obj.a: <input type="text"
				   v-model="obj.a"></p>
	</div>
</template>

<script type="text/ecmascript-6">
export default {
	name: "",
	data() {
		return {
			obj: {
				a: 123
			}
		}
	},
	watch: {
		obj: {
			handler(newVal, oldVal) {
				console.log('obj.a changed');
			},
			// 深度监听对象
			deep: true
		}
	}
}
</script>

deep的意思就是深入观察,监听器会一层层的往下遍历,给对象的所有属性都加上这个监听器,但是这样性能开销就会非常大了,任何修改obj里面任何一个属性都会触发这个监听器里的 handler。

优化,我们可以是使用字符串形式监听

<template>
	<div>
		<p>obj.a: {{obj.a}}</p>
		<p>obj.a: <input type="text"
				   v-model="obj.a"></p>
	</div>
</template>

<script type="text/ecmascript-6">
export default {
	name: "",
	data() {
		return {
			obj: {
				a: 123
			}
		}
	},
	watch: {
		'obj.a  ': { // 字符串形式监听
			handler(newVal, oldVal) {
				console.log('obj.a changed');
			},
			// deep: true
		}
	}
}
</script>

注意: 不要在 computedwatch 中修改被依赖(或者被监听)的值,这样可能会导致无限循环

posted @ 2022-07-20 18:15  猫老板的豆  阅读(149)  评论(1编辑  收藏  举报