-
早期流行的 JQuery 也是通过操作 DOM 实现
Vue 中更多的是通过数据驱动的方式实现交互,但有时候避免不了仍然需要操作 DOM
通过 ref 标识获取/引用 DOM 节点或组件实例,如本地或第三方组件库
早期版本使用 ref 包;注意两者使用方式的区别
import { useTemplateRef } from 'vue'
- Application
-
焦点管理:当需要自动聚焦到输入框或其它表单元素时
与第三方库交互:例如集成某些需要直接 DOM 节点的 JavaScript 库(如Chart.js)
执行动画:当需要对元素执行复杂的动画效果,而这些效果难以通过 CSS 实现时
文件上传:触发文件选择器等原生控件的操作
测量尺寸:获取元素的宽度、高度等信息用于布局调整
-
直接获取会失败,应在组件 挂载完毕 onMounted 再获取
使用时,应判断是否为空
该属性并不显示在结构中,F12 检查元素时,不可见
- 获取普通 DOM 节点
-
拿到 DOM 节点,就拿到了该元素的所有信息
<div ref="dom"
class="base active"
style="color: #f40;padding: 10px;"
data-ind="100" >
hi,there
<span>88</span>
</div>
import { useTemplateRef, onMounted } from 'vue'
let dom = useTemplateRef('dom')
onMounted(() => {
console.log(dom);
console.log(dom.value);
console.log(dom.value.innerText);
console.log('nodes', dom.value.childNodes[0]);
console.log('children', dom.value.children[0]);
console.log('classList', dom.value.classList);
console.log('className', dom.value.className);
console.log('style', dom.value.style);
console.log('getAttribute', dom.value.getAttribute('data-ind'));
console.log('getAttribute', dom.value.getAttribute('style'));
console.log('getAttribute', dom.value.getAttribute('class'));
})
- 获取组件
-
返回组件实例
默认情况下,组件内部的属性和方法对外部不公开,所以获取到的 ref 仅仅是一个代理对象,看不到组件的内部细节
defineExpose 应该写在暴露的对象后面
<template>
<div @click="getTitle">only for test - {{ title }}</div>
</template>
<script setup>
import { ref } from 'vue';
let title = ref(18)
function getTitle() {
console.log(title.value);
}
defineExpose({
title,
getTitle
})
</script>
refs can be useful in certain situations where direct access to a child component's internal state
or methods is necessary.
尽量避免通过 ref 引用组件,请使用组件的通信机制 props 和emit;详见后续组件内容
Remember that accessing a child component's data directly using refs can make your components
tightly coupled. Consider using props and events for communication between components
- [] 单击打开弹窗;更多信息,请访问 实操 - Modal
- 父组件获取子组件|弹窗组件实例,执行弹窗的方法
- 子组件|弹窗组件定义方法并暴露;方法利用 bool 将弹窗组件的隐藏状态变为显示
- 多ref
-
列表渲染中指定 ref,将获取多个元素
必须声明为数组 [] 形式,否则无法遍历
不建议每个子节点都标注 ref 属性
建议获取父节点,再根据节点关系获取子节点
<div v-for="(item,index) in 10" ref="navRef">{{item}}</div>
const navRef = useTemplateRef('navRef')
onMounted(() => {
navRef.value.forEach(item => {
console.log(item.innerHTML);
})
})