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 是响应式引用。

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

相关推荐
weixin_382395231 小时前
为小工厂量身打造:本地部署的物料管理系统带缺料计算
前端·制造
__zRainy__1 小时前
解决pnpm v10+不自动构建
前端·pnpm·工程化
猫猫不是喵喵.2 小时前
Vue3 Props 属性
前端·javascript·vue.js
醉城夜风~3 小时前
CSS元素显示模式(display)
前端·css
AI大模型-小华4 小时前
Codex 三方充值快速入门指南
java·前端·数据库·chatgpt·ai编程·codex·chatgpt pro
做前端的娜娜子6 小时前
同一链接实现 PC Web 与移动 H5 自适应
前端·掘金·金石计划
小帅不太帅6 小时前
架构没变、规模没变,DeepSeek V4 Flash 正式版凭什么暴涨 47 分?
前端·aigc·deepseek
jarvisuni7 小时前
DeepSeekFlash前端依旧拉垮,而且变慢了很多!
前端·javascript·算法
卷福同学8 小时前
AI编程出海第二步:验证关键词能否做站
前端·人工智能·后端