本文介绍在vue3的setup中使用composition API获取元素节点的几种方法:
静态绑定
仅仅需要申明一个ref的引用,用来保存元素,在template中,不必bind引用(:ref="domRef"),只需要声明一个同名的ref属性(ref="domRef")即可。
html复制代码<script setup> import { ref, onMounted } from ''vue'' // 声明一个ref引用,来保存元素 const domRef = ref(null) onMounted(() => { domRef.value.style.background = "red" }) </script> <template> <!-- 这里只需要同名即可 --> <button ref="domRef">dom</button> </template>
需要注意的是,访问的时候,要确保ref引用值已经成功绑定上元素,我们可以使用以下几种方式确保获取:
onMounted
js复制代码onMounted(() => { domRef.value.style.background = "red" })
nextTick
js复制代码nextTick(() => { domRef.value.style.background = "red" })
watchEffect
js复制代码watchEffect(() => { if (domRef.value) { domRef.value.style.background = "red" } })
watch
js复制代码watch(domRef, (val) => { domRef.value.style.background = "red" })
v-for中使用
在使用v-for进行静态绑定时,仅需要注意以下两点:
- 要与
v-for在同级 ref是一个数组ref([])
html复制代码<script setup> import { ref, onMounted } from ''vue'' const list = ref([ /* ... */ ]) const itemRefs = ref([]) onMounted(() => console.log(itemRefs.value)) </script> <template> <ul> <li v-for="item in list" ref="itemRefs"> {{ item }} </li> </ul> </template>
但需要注意的是,itemRefs元素数组并不保证与list数组为相同的顺序。
动态绑定
动态绑定中,分为两种方式,一种是通过将ref设置为函数,第二种则是通过getCurrentInstance方法访问当前组件实例上的$refs;
ref设置函数
html复制代码<template> <button :ref="handleRef">动态Ref</button> </template> <script setup> import { shallowRef } from ''vue'' const btnRef = shallowRef(null) // 赋值动态ref到变量 const handleRef = el => { if (el) { btnRef.value = el } } </script>
ref的函数回调中,我们能够接受到元素返回值,再动态设置到响应式变量即可;
当然,通过设置函数回调的方式,我们也能非常灵活的进行进一步的封装。
html复制代码<template> <ul> <li v-for="item in list" :key="item.id" :ref="(el) => handleLiRef(el, item)"> <button>{{ item.id }}</button> </li> </ul> </template> <script setup> import { ref } from "vue" const list = ref([{ id: "111" }, { id: "222" }, { id: "333" }]) const handleLiRef = (el, item) => { console.log(el, item) } </script>
通过getCurrentInstance方法
html复制代码<template> <ul> <li v-for="item in list" :key="item.id" :ref="item.id"> <button>{{ item.id }}</button> </li> </ul> </template> <script setup> import { getCurrentInstance, onMounted, ref } from "vue" const { proxy } = getCurrentInstance() const list = ref([{ id: "111" }, { id: "222" }, { id: "333" }]) onMounted(() => { console.log(proxy.$refs["111"]) }) </script>
这种方式,与vue2的this.$refs一般无二,只是我们用了getCurrentInstance函数在setup中获取了当前组件实例以替代this。
获取vue实例
需要注意的是,无论通过以上哪种方式获取元素,如果元素为vue组件,则我们只能获得vue实例,而不是一个dom元素;此时我们可以通过ref属性值来获取 vue实例的真实 dom;
html复制代码<script setup> import { ref, onMounted } from ''vue'' // 声明一个ref引用,来保存元素 const domRef = ref(null) onMounted(() => { console.log(domRef.value.ref) }) </script> <template> <!-- 这里只需要同名即可 --> <el-button ref="domRef">vue组件</el-button> </template>
最后
原文链接地址:mp.weixin.qq.com/s/BUQ1_FaX4…
期待你在掘金关注我:油箱上的葱花,也可以在公众号里找到我:COOL前端。