好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

一文详解Vue3中使用ref获取元素节点

前言:

本文介绍在 vue3 的 setup 中使用 composition API 获取元素节点的 几种方法:

静态绑定

仅仅需要申明一个 ref 的引用,用来保存元素,在 template 中,不必 bind 引用( :ref="domRef" ),只需要声明一个同名的 ref 属性( ref="domRef" )即可。

<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

onMounted(()?=>?{
??domRef.value.style.background?=?"red"
})

nextTick

nextTick(()?=>?{
??domRef.value.style.background?=?"red"
})

watchEffect

watchEffect(()?=>?{
???if?(domRef.value)?{
????????domRef.value.style.background?=?"red"
???}
})

watch

watch(domRef,?(val)?=>?{
????domRef.value.style.background?=?"red"
})

v-for中使用

在使用 v-for 进行静态绑定时, 仅需要注意以下两点:

要与 v-for 在同级 ref 是一个数组 ref([])

<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设置函数

<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 的函数回调中,我们能够接受到元素返回值,再动态设置到响应式变量即可;

当然,通过 设置函数回调 的方式,我们也能非常灵活的进行进一步的封装。

<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方法

<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 组件,则需要在子组件中使用 defineExpose 进行暴露。

在父组件中,我们静态绑定 childRef 。

<template>
????<Test?ref="childRef"></Test>
</template>

<script?setup?lang="ts">
????import?Test?from?"./components/test.vue"
????import?{?onMounted,?ref?}?from?"vue"

????const?childRef?=?ref(null)
????onMounted(()?=>?{
????????console.log(childRef.value.btnRef)
????})
</script>

在子组件中,我们需要通过 defineExpose 函数,手动暴露出来 ref 引用值,该值指向了 button 元素。

<template>
????<button?ref="btnRef">子组件</button>
</template>

<script?setup>
????import?{?ref?}?from?"vue"
????const?btnRef?=?ref(null)
????defineExpose({
????????btnRef
????})
</script>

到此这篇关于一文详解Vue3中使用ref获取元素节点的文章就介绍到这了,更多相关Vue3 ref 获取元素节点内容请搜索以前的文章或继续浏览下面的相关文章希望大家以后多多支持!

查看更多关于一文详解Vue3中使用ref获取元素节点的详细内容...

  阅读:48次