首页 > 网页制作 >Vue.js provide/inject 传递响应式引用的正确用法

Vue.js provide/inject 传递响应式引用的正确用法

来源:互联网 2026-06-30 08:17:01

Vue 3 组合式 API 中 provide/inject 传递 ref 的核心陷阱 在 Vue 3 组合式 API 里,用 provide 传递 ref 对象时,最容易踩的坑之一就是:子组件通过 inject 拿到的到底是 ref 本身,还是它背后那个 .value。 关键判断:provide

Vue 3 组合式 API 中 provide/inject 传递 ref 的核心陷阱

在 Vue 3 组合式 API 里,用 provide 传递 ref 对象时,最容易踩的坑之一就是:子组件通过 inject 拿到的到底是 ref 本身,还是它背后那个 .value

关键判断:provide 传 ref 是正确的做法

你可能已经知道,provideref 是正确的做法,例如:

长期稳定更新的攒劲资源: >>>点此立即查看<<<

const selectedReceipt = ref([]);
provide('selectedReceipt', selectedReceipt);

到这里没问题,你给出去的确实是一个 Ref 实例。但到了子组件那边,很多人会下意识地想:在模板里是不是应该手动写 .value?其实不是。

子组件注入得到的 ref 在模板中自动解包

子组件注入得到的 selectedReceipt 本身就是一个 Ref 类型的对象——它包含了 .value 属性,但在模板里反而不能直接用 .value

为什么?因为 Vue 3 的模板语法对 Ref 类型有自动解包机制。简单说,当你写 selectedReceipt.id 的时候,Vue 模板会自动帮你读取 selectedReceipt.value.id。如果你非要写成 selectedReceipt.value.id,不仅冗余,而且会在首次渲染时因为响应式依赖没被正确触发而报 undefined——这个错误非常隐蔽,抓狂是常有的事。

正确写法与常见错误

来看正确的写法:

Print

而下面这种写法,就是典型的“踩坑”姿势:

Print

逻辑代码与模板是两个截然不同的世界

这里尤其要敲黑板:逻辑代码和模板,是两个截然不同的世界。

  • 在模板里:selectedReceipt.id 就够,Vue 会帮你自动解包,但仅限于顶层属性的访问。比如 selectedReceipt.hospitals.en_name 仍然正确,因为模板解包只作用于 selectedReceipt 这个顶层 Ref,后续的链式访问是你自己的逻辑。
  • 在 JavaScript 逻辑里(比如 setup()watchcomputed 中):你必须显式写 .value。因为这里没有模板的自动解包,你需要手动告诉 Vue:“我要读这个 ref 的当前值”。

watch 监听对象必须是 .value

还有一点很容易忽略:watch 监听的对象应该是 .value,而不是 ref 本身。

你现在写的 watch(() => selectedReceipt, ...) 实际上监听的是 selectedReceipt 这个引用是否变成了另一个对象——这几乎不会发生。你要监听的是它的 变化:

watch(() => selectedReceipt.value, (newVal) => {
  if (newVal && newVal.length > 0) {
    const receipt = newVal[0];
    master_Filter.value.hospital_id = receipt.hospitals.en_name;
    master_Filter.value.assessment_date = receipt.assessment_date;
    master_Filter.value.maktoob_no = receipt.maktoob_no;
    master_Filter.value.maktoob_date = receipt.maktoob_date;
    getDetails();
  }
}, { immediate: true, deep: true });

防御性检查不可省略

这里还有个小细节:selectedReceipt 初始值是 ref([]),所以首次注入时,selectedReceipt.value 是空数组。访问 selectedReceipt.value.id 肯定是个 undefined。所以 防御性检查 不能省——在模板里用可选链 .id,在 watch 里加判空逻辑,都是好习惯。

最佳实践总结

  1. provide 传的是 refinject 接收到的也是 ref
  2. 模板里直接用 injectedRef.prop,Vue 会自动解包。
  3. JavaScript 逻辑里必须统一用 injectedRef.value
  4. watch 监听 () => injectedRef.value,配合 immediate: true 保证初始值触发。
  5. 对可能为空的数据(比如 selectedReceipt.value[0]),始终做存在性校验。

这套规则吃透了,selectedReceipt 在模板里报 undefined、链接跳转失败的问题就能彻底解决,响应式更新也会稳稳当当。

侠游戏发布此文仅为了传递信息,不代表侠游戏网站认同其观点或证实其描述

热游推荐

更多
湘ICP备14008430号-1 湘公网安备 43070302000280号
All Rights Reserved
本站为非盈利网站,不接受任何广告。本站所有软件,都由网友
上传,如有侵犯你的版权,请发邮件给xiayx666@163.com
抵制不良色情、反动、暴力游戏。注意自我保护,谨防受骗上当。
适度游戏益脑,沉迷游戏伤身。合理安排时间,享受健康生活。