Vue3父子组件数据双向同步实现方法

在 Vue 3 中,实现父子组件间双向同步响应式对象的步骤如下:

实现思路

  1. 父组件 通过 v-model 传递响应式对象。

  2. 子组件接收并深拷贝为本地副本。

  3. 子组件监听父组件的数据变化,更新本地副本(不触发同步)。

  4. 子组件监听本地副本的变化,触发同步事件(排除父组件更新引起的变更)。

  5. 使用标志位 isUpdatingFromParent 区分变更来源,避免循环更新。

代码实现

父组件

vue

复制代码
<template>
  <Child v-model="parentData" />
</template>

<script setup>
import { ref } from 'vue'
import Child from './Child.vue'

const parentData = ref({
  name: 'Parent',
  info: { id: 1 }
})
</script>
子组件

vue

复制代码
<template>
  <input v-model="localCopy.name">
  <input v-model="localCopy.info.id" type="number">
</template>

<script setup>
import { ref, watch, nextTick } from 'vue'

const props = defineProps({
  modelValue: {
    type: Object,
    required: true
  }
})

const emit = defineEmits(['update:modelValue'])

// 深拷贝创建本地副本
const localCopy = ref(JSON.parse(JSON.stringify(props.modelValue)))

// 标志位:是否来自父组件的更新
let isUpdatingFromParent = false

// 监听父组件数据变化
watch(
  () => props.modelValue,
  async (newVal) => {
    isUpdatingFromParent = true
    localCopy.value = JSON.parse(JSON.stringify(newVal)) // 深拷贝更新
    await nextTick()
    isUpdatingFromParent = false
  },
  { deep: true }
)

// 监听本地副本变化
watch(
  localCopy,
  (newVal) => {
    if (!isUpdatingFromParent) {
      emit('update:modelValue', JSON.parse(JSON.stringify(newVal)))
    }
  },
  { deep: true }
)
</script>

关键点说明

  1. 深拷贝处理 :使用 JSON.parse(JSON.stringify()) 确保副本与原数据无引用关系。

  2. 双向监听机制

    • 父 → 子:监听 props.modelValue,更新副本时标记来源,避免触发同步。

    • 子 → 父:监听 localCopy,非父组件更新时触发同步事件。

  3. 防循环处理 :通过 isUpdatingFromParentnextTick() 确保父组件更新不会触发子组件同步。

注意事项

  • 性能优化 :深拷贝不适合大型对象,可改用 structuredClone 或工具库(如 lodash 的 _.cloneDeep)。

  • 响应式类型 :如果父组件使用 reactive(),需确保 props.modelValue 是响应式引用。

  • 结构稳定性:对象结构变化(增删属性)时,需重新深拷贝避免数据不一致。

相关推荐
代码搬运媛7 小时前
Jest 测试框架详解与实现指南
前端
counterxing7 小时前
我把 Codex 里的 Skills 做成了一个 MCP,还支持分享
前端·agent·ai编程
wangqiaowq8 小时前
windows下nginx的安装
linux·服务器·前端
之歆8 小时前
DAY_12JavaScript DOM 完全指南(二):实战与性能篇
开发语言·前端·javascript·ecmascript
发现一只大呆瓜8 小时前
Vite凭什么这么快?3分钟带你彻底搞懂 Vite 热更新的幕后黑手
前端·面试·vite
Maimai108088 小时前
React如何用 @microsoft/fetch-event-source 落地 SSE:比原生 EventSource 更灵活的实时推送方案
前端·javascript·react.js·microsoft·前端框架·reactjs·webassembly
candyTong8 小时前
Claude Code 的 Edit 工具是怎么工作的
javascript·后端·架构
kyriewen10 小时前
产品经理把PRD写成“天书”,我用AI半小时重写了一遍,他当场愣住
前端·ai编程·cursor
humcomm10 小时前
元框架的工作原理详解
前端·前端框架
canonical_entropy11 小时前
Attractor Before Harness: AI 大规模开发的方法论
前端·aigc·ai编程