全国免费咨询:

13245491521

VR图标白色 VR图标黑色
X

中高端软件定制开发服务商

与我们取得联系

13245491521     13245491521

2025-06-23_同事用了个@vue∶mounted,我去官网找了半天没找到

您的位置:首页 >> 新闻 >> 行业资讯

同事用了个@vue∶mounted,我去官网找了半天没找到 前言大家好,我是奈德丽。 上周在做代码review的时候,看到同事小李写了这样一行代码: component :is="currentComponent" @vue:mounted="handleMounted" / 我第一反应是:"这什么语法?似曾相识的样子,有点像在vue2中用过的@hook:mounted, 但我们项目是vue3,然后去Vue3官方文档搜索@vue:mounted,结果什么都没找到,一开始我以为是他研究了源码,结果他说是百度到的,那我们一起来来研究研究这个东西吧。 从一个动态组件说起小李的需求其实很简单:在子组件加载或更新或销毁后,需要获取组件的某些信息。这家伙是不是还看源码了,有这种骚操作,他的代码是这样的: template div class="demo-container" 动态组件加载监控/h2 div class="status"当前组件状态:{{ componentStatus }}/div div class="controls" button @click="loadComponent('ComponentA')"加载组件A/button button @click="loadComponent('ComponentB')"加载组件B/button button @click="unloadComponent"卸载组件/button /div !-- 小李写的代码 -- component :is="currentComponent" v-if="currentComponent" @vue:mounted="handleMounted" @vue:updated="handleUpdated" @vue:beforeUnmount="handleBeforeUnmount" / /div /template script setup import { ref } from 'vue' const currentComponent = ref(null) const componentStatus = ref('无组件') const handleMounted = () = { componentStatus.value = '? 组件已挂载' console.log('组件挂载完成') } const handleUpdated = () = { componentStatus.value = '?? 组件已更新' console.log('组件更新完成') } const handleBeforeUnmount = () = { componentStatus.value = '? 组件即将卸载' console.log('组件即将卸载') } const loadComponent = (name) = { currentComponent.value = name } const unloadComponent = () = { currentComponent.value = null componentStatus.value = '无组件' } /script 我仔细分析了一下,在这个动态组件的场景下,@vue:mounted确实有它的优势。最大的好处是「只需要在父组件一个地方处理」,不用去修改每个可能被动态加载的子组件。想象一下,如果有十几个不同的组件都可能被动态加载,你得在每个组件里都加上emit事件,维护起来确实麻烦。 而用@vue:mounted的话,所有的生命周期监听逻辑都集中在父组件这一个地方,代码看起来更集中,也更好管理。 但是,我心里还是有疑虑:「这个语法为什么在官方文档里找不到?」 深入探索:未文档化的功能经过一番搜索,我在Vue的GitHub讨论区找到了答案。原来这个功能确实存在,但Vue核心团队明确表示: ?"这个功能不是为用户应用程序设计的,这就是为什么我们决定不文档化它。" ?引用来源: https://github.com/orgs/vuejs/discussions/9298 换句话说: ? 这个功能确实存在且能用? 但官方不保证稳定性?? 可能在未来版本中被移除?? 不推荐在生产环境使用我们来看一下vue迁移文档中关于Vnode的部分,关键点我用下划线标红了。有趣的是这个@vue:[生命周期]语法不仅可以用在组件上,也可以用在所有虚拟节点中。 虽然在Vue 3迁移指南中有提到从@hook:(Vue 2)改为@vue:(Vue 3)的变化,但这更多是为了兼容性考虑,而不是鼓励使用。 为什么小李的代码"看起来"没问题?回到小李的动态组件场景,@vue:mounted确实解决了问题: 「集中管理」- 所有生命周期监听逻辑都在父组件一个地方「动态性强」- 不需要知道具体加载哪个组件「代码简洁」- 不需要修改每个子组件「即用即走」- 临时监听,用完就完但问题在于,这是一个「不稳定的API」,随时可能被移除。 我给出的review意见考虑到安全性和稳定性,还是以下方案靠谱 方案一:子组件主动汇报(推荐)虽然需要修改子组件,但这是最可靠的方案: !-- ComponentA.vue -- template div class="component-a" 我是组件A/h3 button @click="counter++"点击次数: {{ counter }}/button /div /template script setup import { ref, onMounted, onUpdated, onBeforeUnmount } from 'vue' const emit = defineEmits(['lifecycle']) const counter = ref(0) onMounted(() = { emit('lifecycle', { type: 'mounted', componentName: 'ComponentA' }) }) onUpdated(() = { emit('lifecycle', { type: 'updated', componentName: 'ComponentA' }) }) onBeforeUnmount(() = { emit('lifecycle', { type: 'beforeUnmount', componentName: 'ComponentA' }) }) /script !-- ComponentB.vue -- template div class="component-b" 我是组件B/h3 input v-model="text" placeholder="输入文字" {{ text }} /div /template script setup import { ref, onMounted, onUpdated, onBeforeUnmount } from 'vue' const emit = defineEmits(['lifecycle']) const text = ref('') onMounted(() = { emit('lifecycle', { type: 'mounted', componentName: 'ComponentB' }) }) onUpdated(() = { emit('lifecycle', { type: 'updated', componentName: 'ComponentB' }) }) onBeforeUnmount(() = { emit('lifecycle', { type: 'beforeUnmount', componentName: 'ComponentB' }) }) /script 父组件使用: component :is="currentComponent" v-if="currentComponent" @lifecycle="handleLifecycle" / script setup const handleLifecycle = ({ type, componentName }) = { const statusMap = { mounted: '? 已挂载', updated: '?? 已更新', beforeUnmount: '? 即将卸载' } componentStatus.value = `${componentName} ${statusMap[type]}` console.log(`${componentName} ${type}`) } /script 「优点」:稳定可靠,官方推荐 「缺点」:需要修改每个子组件,有一定的重复代码 方案二:通过ref访问(适合特定场景)如果你确实需要访问组件实例: component :is="currentComponent" v-if="currentComponent" ref="dynamicComponentRef" / script setup import { ref, watch, nextTick } from 'vue' const dynamicComponentRef = ref(null) // 监听组件变化 watch(currentComponent, async (newComponent) = { if (newComponent) { await nextTick() console.log('组件实例:', dynamicComponentRef.value) componentStatus.value = '? 组件已挂载' // 可以访问组件的方法和数据 if (dynamicComponentRef.value?.someMethod) { dynamicComponentRef.value.someMethod() } } }, { immediate: true }) /script 「优点」:可以直接访问组件实例和方法 「缺点」:只能监听到挂载,无法监听更新和卸载 方案三:provide/inject(深层通信)如果是复杂的嵌套场景,组件层级深的时候我们可以使用这个: !-- 父组件 -- script setup import { provide, ref } from 'vue' const componentStatus = ref('无组件') const lifecycleHandler = { onMounted: (name) = { componentStatus.value = `? ${name} 已挂载` console.log(`${name} 已挂载`) }, onUpdated: (name) = { componentStatus.value = `?? ${name} 已更新` console.log(`${name} 已更新`) }, onBeforeUnmount: (name) = { componentStatus.value = `? ${name} 即将卸载` console.log(`${name} 即将卸载`) } } provide('lifecycleHandler', lifecycleHandler) /script template div div class="status"{{ componentStatus }}/div component :is="currentComponent" v-if="currentComponent" / /div /template !-- 子组件 -- script setup import { inject, onMounted, onUpdated, onBeforeUnmount } from 'vue' const lifecycleHandler = inject('lifecycleHandler', {}) const componentName = 'ComponentA' // 每个组件设置自己的名称 onMounted(() = { lifecycleHandler.onMounted?.(componentName) }) onUpdated(() = { lifecycleHandler.onUpdated?.(componentName) }) onBeforeUnmount(() = { lifecycleHandler.onBeforeUnmount?.(componentName) }) /script 「优点」:适合深层嵌套,可以跨多层传递 各种方案的对比方案实现难度可靠性维护性集中管理适用场景emit事件??????????????? 大部分场景的首选ref访问???????????需要调用组件方法时provide/inject?????????????深层嵌套组件通信@vue:mounted??????? 自己项目可以玩玩,不推荐生产使用总结通过这次code review,我们学到了: 「技术选型要考虑长远」- 不是所有能用的功能都应该用,稳定性比便利性更重要 「特定场景的权衡」- 在动态组件场景下,@vue:[生命周期]确实有集中管理的优势,但要权衡风险 「迁移策略很重要」- 不能一刀切,要有合理的过渡方案 「代码review的价值」- 不仅仅是找bug,更是知识分享和技术决策的过程 「文档化的重要性」- 未文档化的API往往意味着不稳定,使用时要谨慎 虽然@vue:[生命周期]在动态组件场景下确实好用,但从工程化角度考虑,还是建议逐步迁移到官方推荐的方案。毕竟,今天的便利可能是明天的技术债务。 当然,如果你正在维护老项目,且迁移成本较高,也可以考虑先保留现有代码,但一定要有明确的迁移计划和风险控制措施。 恩恩……懦夫的味道 关注更多AI编程资讯请去AI Coding专区:https://juejin.cn/aicoding点击"阅读原文"了解详情~ 阅读原文

上一篇:2024-08-22_《黑神话 ∶ 悟空》 , 为何选择了京东 下一篇:2022-05-13_「营销看点」4月精彩案例复盘,给你好看!

TAG标签:

18
网站开发网络凭借多年的网站建设经验,坚持以“帮助中小企业实现网络营销化”为宗旨,累计为4000多家客户提供品质建站服务,得到了客户的一致好评。如果您有网站建设网站改版域名注册主机空间手机网站建设网站备案等方面的需求...
请立即点击咨询我们或拨打咨询热线:13245491521 13245491521 ,我们会详细为你一一解答你心中的疑难。
项目经理在线

相关阅读 更多>>

猜您喜欢更多>>

我们已经准备好了,你呢?
2022我们与您携手共赢,为您的企业营销保驾护航!

不达标就退款

高性价比建站

免费网站代备案

1对1原创设计服务

7×24小时售后支持

 

全国免费咨询:

13245491521

业务咨询:13245491521 / 13245491521

节假值班:13245491521()

联系地址:

Copyright © 2019-2025      ICP备案:沪ICP备19027192号-6 法律顾问:律师XXX支持

在线
客服

技术在线服务时间:9:00-20:00

在网站开发,您对接的直接是技术员,而非客服传话!

电话
咨询

13245491521
7*24小时客服热线

13245491521
项目经理手机

微信
咨询

加微信获取报价