vue3子组件获取并修改父组件的值

在子组件中,父组件传递来的 prop 是只读的,但是确实有修改的需求,故此做个小小研究

复制代码
// 父组件使用模版:@update:xxx="dialogVisible = $event"
// 子组件使用模版
// const emits = defineEmits(['update:xxx']);
// emits('update:xxx',false)


// 父组件
// :dialogVisible="dialogVisible"  向子组件传值(查询用)
// @update:dialogVisible="dialogVisible = $event" 向子组件传值(可修改)
<HelloWorld
    :dialogVisible="dialogVisible" 
    @update:dialogVisible="dialogVisible = $event"
></HelloWorld>

const dialogVisible = ref(false)

// 子组件
// 接收父组件的数据和方法
const parentData = defineProps(['dialogVisible']);
// 接收父组件需要修改的值
const emits = defineEmits(['update:dialogVisible']);

const onReset = ()=>{
  // 子组件执行修改父组件值
  emits('update:dialogVisible',false)
  console.log('emits','修改成功');

  console.log('parentData.dialogVisible 1',parentData.dialogVisible); // true

  nextTick(()=>{
  	console.log('parentData.dialogVisible 2',parentData.dialogVisible); // false
  })
    
  setTimeout(()=>{
    console.log('parentData.dialogVisible 2',parentData.dialogVisible); // false
  },0)
}

小现象

在子组件修改 dialogVisible 值后立即从父组件再获取并打印时发现值并未立即修改

为什么会打印旧值?

  1. emit 是同步的:事件触发是同步操作

  2. 状态更新是同步的:在父组件的事件处理函数中,状态赋值是同步的

  3. prop 传递是异步的:Vue 的响应式系统更新和重新渲染是异步的

  4. 组件更新顺序

    • 子组件触发 emit

    • 父组件同步更新自己的状态

    • 父组件状态更新后,需要重新渲染才能将新值传递给子组件

    • 在子组件的 emit 方法后立即打印,此时父组件尚未完成重新渲染

执行流程详解

  1. 子组件调用 emits('update:dialogVisible', false)

  2. 父组件的 @update:dialogVisible 处理函数执行

  3. 父组件同步更新 dialogVisible = false

  4. 此时在父组件处理函数中打印 dialogVisible 会显示 false

  5. 但在子组件中,props.dialogVisible 不会立即更新

  6. Vue 开始异步更新过程(下一个 tick)

  7. 父组件重新渲染,将新值传递给子组件

  8. 子组件接收到新的 prop 值

相关推荐
weixin_395448916 小时前
main.c_cursor_0130
前端·网络·算法
C澒6 小时前
SGW 接入层运维实战:配置查看 + 监控分析 + 日志排查
前端·安全·运维开发
德育处主任Pro7 小时前
『NAS』在群晖部署一款太空策略游戏-ogame-vue-ts
前端·vue.js·游戏
ziqi5227 小时前
第二十五天笔记
前端·chrome·笔记
GISer_Jing7 小时前
Memory、Rules、Skills、MCP如何重塑AI编程
前端·人工智能·aigc·ai编程
xcs194057 小时前
前端 项目构建问题 \node_modules\loader-runner\lib\loadLoader.js
开发语言·前端·javascript
广然7 小时前
EVE-NG 镜像管理工具 1.1 Web 版本正式发布!
运维·服务器·前端
Data_Journal7 小时前
【无标题】
大数据·服务器·前端·数据库·人工智能
我爱加班、、8 小时前
new Map()+Array.from()整理elementPlus的级联器数据
linux·前端·javascript
Hx_Ma168 小时前
Map集合的5种遍历方式
java·前端·javascript