我们来看下使用引号来监听对象的嵌套值的变化。 什么意思呢,我们直接来看下例子。 假设我们有一个 User组件,为了说明本节的内容,这里我们使用选项 API 方式来写这个组件,如下所示:
<template>
<div>
<p>姓名: {{ userInfo.details.name }}</p>
<p>职业 {{ userInfo.job }}</p>
<p>年龄: {{ userInfo.age }}</p>
</div>
</template>
<script>
export default {
props: {
userInfo: Object
},
watch: {
userInfo: {
handler() {
console.log('userInfo 的值发生变化了!');
},
deep: true
}
},
data() {
return {};
},
created() {},
mounted() {},
methods: {}
};
</script>
<style lang="scss"></style>
UserInfo 组件接受一个参数对象 userInfo ,在 userInfo 中又有一个 details 对象,该对象包含一个 name 属性,然后,我们在 template 中把 name、job、age 展示出来。
在父组件中引入 userInfo 组件:
<template>
<UserInfo :userInfo="userInfo" />
<van-button plain hairline type="primary" @click="updeteUserName">改变姓名</van-button>
</template>
<script setup lang="ts">
import UserInfo from 'Components/UserInfo.vue';
const userInfo = reactive({
details: {
name: '羊羊羊'
},
job: '前端工程师',
age: 15
});
const updeteUserName = () => {
userInfo.details.name = '张三';
};
</script>
<style scoped></style>
当我们点击按钮时,在点击事件中改变了 name 属性的值,这对大家来说都好理解。
运行:
假设,某些场景下,在 UserInfo 组件中,传入的 userInfo 对象发生变化,我们需要做些事情。要监听对象的变化。我们可以使用 watch 来监听,但 watch 直接监听对象时,手动修改对象的某个属性值会发现,监听并没有生效,此时我们需要用到 watch 中的 deep 属性,当 deep 为 true 时,它会一层层的遍历给对象的所有属性都加上这个监听函数,这样可以检测到对象的每个属性的变化。
export default {
props: {
userInfo: Object
},
watch: {
userInfo: {
handler() {
console.log('userInfo 的值发生变化了!');
},
deep: true
}
}
};
但是这样会存在一个问题,我们只要监听 name 的变化而不是监听对象的所有属性变化,这时又要怎么做呢? 在 Vue3 的组合 API中,我们可以这么做:
watch(
() => userInfo.details.name,
() => {
console.log('name 发生变化了');
}
);
在选项 API 中,我们可以使用引号来监听嵌套值:
watch: {
'userInfo.details.name'() {
console.log('name 的值发生变化了!');
}
}