vue3.5中的useTemplateRef
文章类型:Vue
发布者:hp
发布时间:2024-11-18
vue3访问DOM和子组件使用ref进行模板引用,这就会产生一个问题,到底ref是个响应数据还是DOM元素,
1:定义响应数据
const inputEl =ref(null)
2:传统ref定义在DOM上
<input type="text" ref="inputEl" />
const inputEl = ref<HTMLInputElement>();
export default function useRef() {
const inputEl = ref<HTMLInputElement>();
function setInputValue() {
if (inputEl.value) {
inputEl.value.value = "Hello";
}
}
return {
inputEl,
setInputValue,
};
}
const { setInputValue, inputEl } = useInput();
所以,Vue3.5发现了这个问题,新增了useTemplateRef函数
1:定义:接受一个参数key,是一个字符串,返回一个ref变量
const inputEl = useTemplateRef<HTMLInputElement>("inputRef");
function setInputValue() {
if (inputEl.value) {
inputEl.value.value = "Hello";
}
}
导出使用,就不需要再导出变量值
export default function useInput(key) {
const inputEl = useTemplateRef<HTMLInputElement>(key);
function setInputValue() {
if (inputEl.value) {
inputEl.value.value = "Hello, world!";
}
}
return {
setInputValue,
};
}
function useTemplateRef(key) {
const i = getCurrentInstance();
const r = shallowRef(null);
if (i) {
const refs = i.refs === EMPTY_OBJ ? (i.refs = {}) : i.refs;
Object.defineProperty(refs, key, {
enumerable: true,
get: () => r.value,
set: (val) => (r.value = val),
});
}
return r;
}
1:使用getCurrentInstance方法获取当前vue实例对象,赋值给变量i
2:调用shallowRef函数生成一个浅层的ref对象,初始值为null。
3:判断当前vue实例如果存在就读取实例上面的refs属性对象,如果实例对象上面没有refs属性,那么就初始化一个空对象到vue实例对象的refs属性
4:使用了Object.defineProperty方法对refs属性对象进行拦截,拦截的字段是变量key的值,而这个key的值就是template中使用ref属性绑定的值
5:最后返回这个ref对象
1:useTemplateRef函数主要是更直观的区分ref是DOM还是ref
2:解决定义ref作为DOM元素后,封装成Hooks后导出变量名后必须引入
1:动态绑定ref变量和赋值
<input type="text" :ref="refKey" />
const refKey = ref("inputEl1");
const inputEl1 = useTemplateRef<HTMLInputElement>("inputEl1");
const inputEl2 = useTemplateRef<HTMLInputElement>("inputEl2");
function switchRef() {
refKey.value = refKey.value === "inputEl1" ? "inputEl2" : "inputEl1";
}