「小墨是前端」致力于分享实用前端技术、挖掘优秀的开源项目,带你探索前端的奇妙世界,共同学习进步。
在 Vue3 中,我们通常使用ref来访问 DOM 元素和子组件,进行模板引用。但是ref的一些特性却让人困惑不已。例如,定义的ref变量究竟是响应式数据还是 DOM 元素?为什么模板中ref属性的值明明是一个字符串,却能与script中同名变量绑定?
为了解决这些问题,Vue3.5 推出了一个全新的函数——useTemplateRef,它让模板引用变得更加直观和易用。
传统 ref 模板引用的痛点
我们先来回顾一下 React 中使用ref访问 DOM 元素的方式:
React 中使用useRef函数定义inputEl变量,并将input元素的ref属性设置为该变量,从而可以通过inputEl.current访问到输入框。这种方式简单直接,符合编程直觉。
然而,Vue3 中的ref模板引用却略显 "反直觉":
注意:ref属性接收的是ref变量的名称(字符串),而不是变量本身。
这种方式容易造成混淆,尤其对于刚接触 Vue3 的开发者来说,很容易误将ref变量直接绑定到ref属性上,导致访问 DOM 元素时出现错误。
此外,如果将ref模板引用相关的逻辑封装成 Hooks,情况会更加复杂:
即使在组件中没有直接使用inputEl,也必须从 Hooks 中导入,否则inputEl无法正确绑定到输入框。这种 "隐式依赖" 显得不够优雅。
useTemplateRef 函数闪亮登场
useTemplateRef函数正是为了解决上述问题而设计的。它的用法非常简单:
useTemplateRef接收一个字符串参数作为 key,返回值是一个ref变量,该变量指向模板中ref属性值为 key 的 DOM 元素或子组件。
使用useTemplateRef后,模板引用变得更加清晰和直观:
1. 模板中的ref属性值与useTemplateRef的参数保持一致,易于理解和维护。
2.useTemplateRef的返回值是一个标准的ref变量,可以直接访问 DOM 元素或子组件,符合编程直觉。
Hooks 中的 useTemplateRef
在 Hooks 中使用useTemplateRef可以避免之前提到的 "隐式依赖" 问题:
由于 Hooks 内部处理了inputEl的绑定,组件不再需要导入和维护该变量,代码更加简洁。
动态切换 ref 绑定
useTemplateRef也支持动态切换ref绑定的场景:
通过修改refKey的值,可以动态切换ref属性绑定的变量,实现灵活的模板引用。
useTemplateRef 源码浅析
useTemplateRef的实现原理并不复杂,简化后的代码如下:
1. 获取当前 Vue 实例对象。
2. 创建一个浅层的ref对象r,初始值为null。
3. 如果存在 Vue 实例,则获取实例上的refs属性(用于存储模板引用)。
4. 使用Object.defineProperty对refs对象的key属性进行拦截:
•get拦截:返回r.value,即useTemplateRef返回的ref变量的值。
•set拦截:将val赋值给r.value,从而将 DOM 元素或组件实例绑定到ref变量上。
5. 返回ref对象r。
总结
useTemplateRef是 Vue3.5 中一个非常实用的函数,它解决了传统ref模板引用的一些痛点,让模板引用变得更加直观、易用和灵活。
useTemplateRef的优势:
• 提升代码可读性和可维护性。
• 符合编程直觉,更容易理解和使用。
• 简化 Hooks 中的模板引用逻辑。
• 支持动态切换ref绑定,提升灵活性。
希望本文能帮助你更好地理解和使用useTemplateRef函数,提升 Vue3 开发效率。
创作不易,求点赞、求在看、求转发!你的支持是我创作的最大动力!关注小墨,带你解锁更多前端技能!
领取专属 10元无门槛券
私享最新 技术干货