VueJS 2中如何用计算属性替代watcher更新嵌套v-model
解答
关于计算属性操作嵌套值的疑问
计算属性完全支持读取和联动嵌套响应式值,不存在无法操作嵌套值的问题。官方建议优先使用计算属性的适用场景是需要基于现有响应式数据衍生出可复用的新响应值,你当前的需求是「当某状态满足条件时修改另一状态」,本质是状态联动的副作用操作,本身就是watch的典型适用场景,不需要硬套计算属性的最佳实践,如果你确实需要用计算属性实现,可参考如下方案。
用计算属性替代watch的实现方案
你可以将父组件绑定给子组件的v-model值包装为带get/set的计算属性,在赋值阶段完成状态判断和修正,完整代码如下:
父组件修改后代码
<template lang="pug"> user-component(v-model="formUser") </template> <script> export default { name: "MyForm", components: { UserComponent }, data() { return { apiData: {}, }; }, computed: { formUser: { get() { return this.apiData.user ?? {} }, set(userVal) { // 赋值前判断无国籍状态,自动清空国籍值 if (userVal.stateless) { userVal.nationality = null } this.$set(this.apiData, 'user', userVal) } } }, async mounted() { const response = await ApiService.getData(); this.apiData = response.data; }, }; </script>
子组件补充双向绑定逻辑
你当前的子组件只绑定了props的value,没有向父组件触发更新事件,v-model无法生效,需要补充事件触发逻辑:
<template lang="pug"> b-form-group(label="Nationality") b-form-input(:value="value.nationality" @input="updateField('nationality', $event)) b-form-checkbox(:checked="value.stateless" @change="updateField('stateless', $event)) Stateless </template> <script> export default { name: "UserComponent", props: { value: { type: Object, required: true } }, methods: { updateField(fieldKey, newValue) { this.$emit('input', { ...this.value, [fieldKey]: newValue }) } } }; </script>
方案说明
该实现将原来的watch监听逻辑转移到了计算属性的set方法中,每次子组件提交用户修改时,都会先判断无国籍状态,自动清空国籍字段,完全实现原有需求。
内容的提问来源于stack exchange,提问作者Robert Strauch
相关产品推荐
相关产品推荐

