Vue2父子组件双向同步:封装vue-multiselect父值修改子组件不更新如何解决
问题1解答
- 父组件重渲染的常见触发场景:
- 父组件自身的响应式状态(data/computed/props)发生变更
- 父组件调用
$forceUpdate强制刷新 - 父组件绑定的插槽、事件回调关联的状态发生变化
你在测试场景没有出现问题是因为刚好没有触碰到父组件重渲染的场景,一旦父组件重渲染,子组件内直接修改的prop值会被父组件传入的原始值直接覆盖,之前的修改会丢失,属于不可靠的实现方式。
如果要硬屏蔽警告,可以在Vue实例初始化时设置silent: true,但该配置会屏蔽所有运行时警告,完全不推荐,会掩盖其他潜在问题。
问题2解答
你现在反向同步失效的核心原因是:子组件data里的items仅在初始化时赋值了一次parentItems,后续parentItems发生变化时,items不会自动同步。有两种常见的可靠实现方案:
方案1:添加watch监听prop变化
在子组件中新增对parentItems的监听,值变化时同步更新内部的items即可:
export default { // 原有代码保持不变 watch: { parentItems(newVal) { this.items = newVal }, // 若传入的list会动态变化,也建议加监听同步filteredList list(newVal) { this.filteredList = newVal } } }
方案2:用带get/set的计算属性替代内部data变量(更推荐)
完全删除data里的items变量,改用计算属性实现自动双向同步,不需要手动维护中间状态,代码更简洁:
export default { model: { prop: 'parentItems', event: 'change', }, props: ['multiple', 'list', 'placeholder', 'label', 'parentItems'], data() { return { filteredList: this.list, } }, computed: { items: { get() { // 直接返回父组件传入的prop值,自动同步父组件更新 return this.parentItems }, set(val) { // 子组件修改时直接触发事件通知父组件更新 this.$emit('change', val) this.$emit('filters-changed') } } }, methods: { searchItems(query) { let q = latinize(query.toLowerCase().replace(/\s/g,'')) this.filteredList = this.list.filter(li => latinize(li[this.label].toLowerCase().replace(/\s/g,'')).includes(q)) }, resetItems() { this.items = this.multiple ? [] : null }, }, }
两种方案都可以完美解决父组件重置car为null时子组件不同步的问题,第二种方案代码更简洁,维护成本更低。
内容的提问来源于stack exchange,提问作者narrei
相关产品推荐
相关产品推荐

