概论
watch 监听明确的数据
computed 监听数据并返回计算结果
watchEffect重视监听过程
测试代码
- 子组件
<template>
<div class='box'>
<div>props 监听测试</div>
computed返回的内容的深度属性:{{ configTwo.obj1 && configTwo.obj1.xxx }}
<div></div>
<!-- 成功响应, computed 说明也能监听到深度修改 -->
computed本身:{{ configTwo }}
<div></div>
<data>props返回的是一个reactive对象,可以深度响应:{{ props.config.obj1?.xxx }}</data>
</div>
</template>
<script lang='ts' setup>
import { PropType } from 'vue';
// import { ref, reactive, computed, onMounted, nextTick } from 'vue';
export interface Config {
arr1: Array<IObject>,
obj1?: IObject
}
const props = defineProps({
title: {
type: String,
required: true,
default: 'Default Title'
},
dicts: {
type: Array,
required: true,
default: () => []
},
customClass: {
type: String,
default: ''
},
config: {
type: Object as PropType<Config>,
default: () => ({
arr1: [], obj1: {
arr1: [],
obj1: {
id: 1,
name: "test"
}
}
})
}
})
console.log(props, "props_type_slvnsldjsklfjlks")
console.log(props.config, "snvlkwejrklwejrkwej")
const dicts = computed(() => props.dicts);
const title = computed(() => props.title);
const config = props.config;
console.log(config, "config_slvnsdlfkjskfj");
//可以监听到
watch(config, (val) => {
console.log(val, "vsndskfdlsfksjfjslkjslkfjsdjflks");
})
//可以监听到,对于config的浅属性可以监听到,也就是config的第一层属性可以监听到,再深度就不行了,因为watch是浅监听
watch(props.config, (val) => {
console.log(val, "config_sdkvnnsdks2342")
});
//能监听到,watch对props任何修改都能监听到?
watch(props, (val) => {
console.log(val, "props_23423svdnlfskjfskldjnlerjlkfjsklfjskdf")
})
//返回ref对象
const configTwo = computed(() => props.config)
console.log(configTwo, "configTwo_vsndlsjdfknvskdlskfj")
//watch 对于ref对象 默认是浅监听,不能监听到ref对象的深度变化,需要开启deep
watch(configTwo, () => {
console.log(configTwo.value, "config_two_sdkvnnsdks2342")
}, {
deep: true,
})
//监听不到ref对象的深度属性,watch 默认是浅监听,不能监听对象的深度属性
watch(configTwo, () => {
console.log(configTwo.value, "vnsldnnvsldfklwe2342sdskjfskdf")
})
watchEffect(() => {
//watchEffect 是深度监听,能监听到ref对象的深层次数据的变化
console.log(configTwo.value, "config_two_effect_sdkvnnsdks2342")
})
const obj1 = computed(() => props.config.obj1); //直接指明监听属性,不开启深度监听也能监听到
//这样可以监听到
watch(obj1, () => {
console.log(obj1.value, "obj1_sdkvnnsdks2342")
})
//可以监听到,watchEffect是深度监听
watchEffect(() => {
console.log(props.config, "config_effect_sdkvnnsdks2342")
})
/**
* 总结:
* watch 第一次加载不会执行,且是浅监听,一般只能监听到对象属性的第一层,对于深度属性不能监听到,需要指明deep配置才能深度监听
*
* watchEffect 是深度监听,且第一次加载就会执行
*
* computed 计算属性也是深度监听,对于深度有任何变化都会反应计算,computed和watchEffect差不多,只是computed会多返回计算结果值,且会缓存,如果内部计算对象没变化就直接读缓存值
*/
/**
* 基本上除了watch默认不是深度监听之外,watchEffect和computed都有深度的响应特性
*/
</script>
<style lang='scss' scoped></style>
- 父组件
<template>
<div class="box">
<div>
<childP :title="'vnslfdjslkfj'" :customClass="'sdfsdf'" :dicts="mydicts" :config="myconfig" />
</div>
</div>
</template>
<script lang="ts" setup>
import childP from "./components/childP.vue";
const mydicts = ref([] as Array<any>);
setTimeout(() => {
mydicts.value = [
{
title: "tom",
age: 20,
},
{
title: "jerry",
age: 22,
}
];
}, 2000);
import {Config} from "./components/childP.vue"
const myconfig=ref<Config>({
arr1:[],
obj1:{
xxx:''
}
})
setTimeout(() => {
// myconfig.value.arr1=[{
// a:"slfjsklfjsdf"
// }]
myconfig.value.obj1!['xxx']="修改了"
console.log(myconfig.value,"snvslkjlskfjsklfjsklfdj")
},5000)
</script>
<style lang="stylus" scoped></style>
总结
- watch 第一次加载不会执行,且是浅监听,一般只能监听到对象属性的第一层,对于深度属性不能监听到,需要指明deep配置才能深度监听
- watchEffect 是深度监听,且第一次加载就会执行
- computed 计算属性也是深度监听,对于深度有任何变化都会反应计算,computed和watchEffect差不多,只是computed会多返回计算结果值,且会缓存,如果内部计算对象没变化就直接读缓存值
- 基本上除了watch默认不是深度监听之外,watchEffect和computed都有深度的响应特性