首頁 > 軟體

一文詳解Vue3中使用ref獲取元素節點

2022-07-27 14:01:07

前言:

本文介紹在vue3setup中使用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>

這種方式,與vue2this.$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 獲取元素節點內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com