欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

一篇文章搞懂Vue3中如何使用ref獲取元素節(jié)點(diǎn)

 更新時(shí)間:2022年11月14日 09:27:41   作者:博客zhu虎康  
過(guò)去在Vue2中,我們采用ref來(lái)獲取標(biāo)簽的信息,用以替代傳統(tǒng) js 中的 DOM 行為,下面這篇文章主要給大家介紹了關(guān)于如何通過(guò)一篇文章搞懂Vue3中如何使用ref獲取元素節(jié)點(diǎn)的相關(guān)資料,需要的朋友可以參考下

前言

雖然在 Vue 中不提倡我們直接操作 DOM,畢竟 Vue 的理念是以數(shù)據(jù)驅(qū)動(dòng)視圖。但是在實(shí)際情況中,我們有很多需求都是需要直接操作 DOM 節(jié)點(diǎn)的,這個(gè)時(shí)候 Vue 提供了一種方式讓我們可以獲取 DOM 節(jié)點(diǎn):ref 屬性。ref 屬性是 Vue2 和 Vue3 中都有的,但是使用方式卻不大一樣,這也導(dǎo)致了很多從 Vue2 轉(zhuǎn)到 Vue3 的小伙伴感到有些困惑。

今天我們就來(lái)揭開(kāi) Vue3 中 ref 的神秘面紗!

1.回顧 Vue2 中的 ref

在學(xué)習(xí) Vue3 中的 ref 之前,我們先來(lái)了解下 Vue2 中 ref,這樣一對(duì)比,大家更能夠加深印象,以及它們之間的區(qū)別。

獲取節(jié)點(diǎn):

這是 ref 的基本功能之一,目的就是獲取元素節(jié)點(diǎn),在 Vue 中使用方式也很簡(jiǎn)單,代碼如下:

<template>
  <div id="app">
    <div ref="hello">小豬</div>
  </div>
</template>
<script>
export default {
  mounted() {
    console.log(this.$refs.hello); // <div>小豬</div>
  },
};
</script>

上段代碼中可以看到我們?cè)?div 元素上綁定了 ref 屬性,并命名為 hello,接下來(lái)我們直接使用 this.$refs.hello 的方式就可以獲取到該 DOM 元素了。

2.Vue3 中 ref 訪問(wèn)元素

Vue3 中通過(guò) ref 訪問(wèn)元素節(jié)點(diǎn)與 Vue2 不太一樣,在 Vue3 中我們是沒(méi)有 this 的,所以當(dāng)然也沒(méi)有 this.$refs。想要獲取 ref,我們只能通過(guò)聲明變量的方式。

創(chuàng)建一個(gè) Vite 項(xiàng)目:

為了方便演示,我們直接在 Vite 項(xiàng)目中演示 ref 代碼,創(chuàng)建項(xiàng)目指令如下:

npm create vite@latest my-vue-app --template vue-ts

代碼如下:

<template>
  <div ref="hello">小豬課堂</div>
</template>
<script setup lang="ts">
import { onMounted, ref } from "vue";
const hello = ref<any>(null);
onMounted(() => {
  console.log(hello.value); // <div>小豬課堂</div>
});
</script>

輸出結(jié)果:

上段代碼中我們同樣給 div 元素添加了 ref 屬性,為了獲取到這個(gè)元素,我們聲明了一個(gè)與 ref 屬性名稱相同的變量 hello,然后我們通過(guò) hello.value 的形式便獲取到了該 div 元素。

注意點(diǎn):

  • 變量名稱必須要與 ref 命名的屬性名稱一致。
  • 通過(guò) hello.value 的形式獲取 DOM 元素。
  • 必須要在 DOM 渲染完成后才可以獲取 hello.value,否則就是 null。

3.v-for 中使用 ref

使用 ref 的場(chǎng)景有多種,一種是單獨(dú)綁定在某一個(gè)元素節(jié)點(diǎn)上,另一種便是綁定在 v-for 循環(huán)出來(lái)的元素上了。這是一種非常常見(jiàn)的需求,在 Vue2 中我們通常使用:ref="…"的形式,只要能夠標(biāo)識(shí)出每個(gè) ref 不一樣即可。

但是在 Vue3 中又不太一樣,不過(guò)還是可以通過(guò)變量的形式接收。

代碼如下:

<template>
  <div ref="hello">小豬課堂</div>
  <ul>
    <li v-for="item in 10" ref="itemRefs">
      {{item}} - 小豬課堂
    </li>
  </ul>
</template>
<script setup lang="ts">
import { onMounted, ref } from "vue";


const itemRefs = ref<any>([]);
onMounted(() => {
  console.log(itemRefs.value);
});
</script>

輸出結(jié)果:

段代碼中盡管是 v-for 循環(huán),但是我們似乎使用 ref 的形式與第 2 節(jié)中的方式?jīng)]有任何變化,我們同樣使用變量的形式拿到了每一個(gè) li 標(biāo)簽元素。

但是這里我們需要注意一下:我們似乎沒(méi)辦法區(qū)分哪個(gè) li 標(biāo)簽?zāi)膫€(gè) ref,初次之外,我們的 itemRefs 數(shù)組不能夠保證與原數(shù)組順序相同,即與 list 原數(shù)組中的元素一一對(duì)應(yīng)。

4.ref 綁定函數(shù)

前面我們?cè)诮M件上定義 ref 時(shí),都是以一個(gè)字符串的形式作為 ref 的名字,其實(shí)我們的 ref 屬性還可以接收一個(gè)函數(shù)作為屬性值,這個(gè)時(shí)候我們需要在 ref 前面加上:。

代碼如下:

<template> 
  <div :ref="setHelloRef">小豬課堂</div>
</template>
<script setup lang="ts">
import { ComponentPublicInstance, HTMLAttributes } from "vue";


const setHelloRef = (el: HTMLElement | ComponentPublicInstance | HTMLAttributes) => {
  console.log(el); // <div>小豬課堂</div>
};
</script>

輸出結(jié)果:

上段代碼中 ref 屬性接收的是一個(gè) setHelloRef 函數(shù),該函數(shù)會(huì)默認(rèn)接收一個(gè) el 參數(shù),這個(gè)參數(shù)就是我們需要獲取的 div 元素。假如需求中我們采用這種方式的話,那么完全可以把 el 保存到一個(gè)變量中去,供后面使用。

那么,我們?cè)?v-for 中是否也能采用這種方式呢?

答案是可以的!

v-for 中使用

代碼如下:

<template>
  <ul>
    <li v-for="item in 10" :ref="(el) => setItemRefs(el, item)">
      {{ item }} - 小豬課堂
    </li>
  </ul>
</template>
<script setup lang="ts">
import { ComponentPublicInstance, HTMLAttributes, onMounted } from "vue";
let itemRefs: Array<any> = [];
const setItemRefs = (el: HTMLElement | ComponentPublicInstance | HTMLAttributes, item:number) => {
  if(el) {
    itemRefs.push({
      id: item,
      el,
    });
  }
}
onMounted(() => {
  console.log(itemRefs);
});
</script>

輸出結(jié)果:

在 v-for 中使用函數(shù)的形式傳入 ref 與不使用 v-for 時(shí)的形式差不多,不過(guò)這里我們做了一點(diǎn)變通,為了區(qū)別出哪個(gè) ref 是哪一個(gè) li 標(biāo)簽,我們決定將 item 傳入函數(shù),也就是(el) => setItemRefs(el, item)的寫(xiě)法。

這種形式的好處既讓我們的操作性變得更大,還解決了 v-for 循環(huán)是 ref 數(shù)組與原數(shù)組順序不對(duì)應(yīng)的問(wèn)題。

5.組件上使用 ref

前面我們所使用 ref 時(shí),都是在一個(gè)具體的 dom 元素上綁定,但是我們也可以將 ref 綁定在組件上,比如在 Vue2 中,我們將 ref 綁定在組件上時(shí),便可以獲取到該組件里面的所有數(shù)據(jù)和方法.

雖然 Vue3 中也可以將 ref 綁定在組件上,但是具體能獲取組件的哪些值還是有一些區(qū)別的,我們一起來(lái)看看。

代碼如下:

<template>
  <child ref="childRef"></child>
</template>
<script setup lang="ts">
import { onMounted, ref } from "vue";
import child from "./child.vue";
const childRef = ref<any>(null);
onMounted(() => {
  console.log(childRef.value); // child 組件實(shí)例
  console.log(childRef.value.message); // undefined
});
</script>

子組件 child 代碼:

<template>
  <div>{{ message }}</div>
</template>
<script lang="ts" setup>
import { ref } from "vue";
const message = ref<string>("我是子組件");
const onChange = () => {};
</script>

輸出結(jié)果:

上段代碼中我們新增了一個(gè)子組件,然后再子組件上面綁定了 ref,其用法基本上和 ref 直接綁定在 DOM 元素上一致。

但是如果我們把 ref 綁定再組件上,通常就是為了調(diào)用子組件里面的方法或者數(shù)據(jù),可是從上面的輸出結(jié)果來(lái)看,我們沒(méi)有獲取到數(shù)據(jù),即 childRef.value.message 為 undefined,這也是與 Vue2 的不同之處。

在 Vue3 中,使用 ref 獲取子組件時(shí),如果想要獲取子組件的數(shù)據(jù)或者方法,子組件可以通過(guò)

defineExpose 方法暴露數(shù)據(jù)。

修改子組件代碼

<template>
  <div>{{ message }}</div>
</template>
<script lang="ts" setup>
import { ref } from "vue";

const message = ref<string>("我是子組件");
const onChange = () => {
  console.log("我是子組件方法")
};
defineExpose({
  message,
  onChange
});
</script>

父組件再次獲取

const childRef = ref<any>(null);
onMounted(() => {
  console.log(childRef.value); // child 組件實(shí)例
  console.log(childRef.value.message); // 我是子組件
  childRef.value.onChange(); // 我是子組件方法
});

輸出結(jié)果:

可以看到我們?cè)诟附M件中可以獲取到子組件暴露的數(shù)據(jù)和方法了。

總結(jié)

雖然 Vue2 和 Vue3 中的 ref 使用方式有著較大的區(qū)別,但是它們的目的都是一樣的,所以我們只要朝著目的前進(jìn),都會(huì)與美好相遇的!

到此這篇關(guān)于通過(guò)一篇文章搞懂Vue3中如何使用ref獲取元素節(jié)點(diǎn)的文章就介紹到這了,更多相關(guān)Vue3用ref獲取元素節(jié)點(diǎn)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Element?el-tag標(biāo)簽圖文實(shí)例詳解

    Element?el-tag標(biāo)簽圖文實(shí)例詳解

    現(xiàn)在好多應(yīng)用場(chǎng)景里會(huì)有一些需要給文章打標(biāo)簽等類似的操作,下面這篇文章主要給大家介紹了關(guān)于Element?el-tag標(biāo)簽的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-04-04
  • nuxt.js中間件實(shí)現(xiàn)攔截權(quán)限判斷的方法

    nuxt.js中間件實(shí)現(xiàn)攔截權(quán)限判斷的方法

    這篇文章主要介紹了nuxt.js中間件實(shí)現(xiàn)攔截權(quán)限判斷的方法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-11-11
  • 深入淺出vue圖片路徑的實(shí)現(xiàn)

    深入淺出vue圖片路徑的實(shí)現(xiàn)

    這篇文章主要介紹了深入淺出vue圖片路徑的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-09-09
  • 解決Vue+ts里面this.$store問(wèn)題

    解決Vue+ts里面this.$store問(wèn)題

    這篇文章主要介紹了解決Vue+ts里面this.$store問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-03-03
  • vue用戶長(zhǎng)時(shí)間不操作退出到登錄頁(yè)的兩種實(shí)現(xiàn)方式

    vue用戶長(zhǎng)時(shí)間不操作退出到登錄頁(yè)的兩種實(shí)現(xiàn)方式

    出于安全考慮,用戶長(zhǎng)時(shí)間不操作,就回到登錄頁(yè)面,讓用戶重新登錄,本文就記錄一下實(shí)現(xiàn)這種效果的兩種方式,具有一定的參考價(jià)值,感興趣的可以了解一下
    2021-09-09
  • 如何解決ElementPlus的el-table底白線問(wèn)題

    如何解決ElementPlus的el-table底白線問(wèn)題

    這篇文章主要介紹了如何解決ElementPlus的el-table底白線問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-12-12
  • vue中的proxyTable反向代理(親測(cè)有用)

    vue中的proxyTable反向代理(親測(cè)有用)

    這篇文章主要介紹了vue中的proxyTable反向代理(親測(cè)有用),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-04-04
  • Vue3中如何使用SCSS編寫(xiě)樣式

    Vue3中如何使用SCSS編寫(xiě)樣式

    在Vue模板中啟用這些表現(xiàn)力庫(kù)插件的最簡(jiǎn)單方法是在初始化項(xiàng)目時(shí)安裝它們,或使用 npm install(或 yarn add)安裝包,這篇文章主要介紹了Vue3中如何使用SCSS編寫(xiě)樣式,需要的朋友可以參考下
    2023-12-12
  • vue中v-if?和v-permission?共同使用的坑及解決方案

    vue中v-if?和v-permission?共同使用的坑及解決方案

    這篇文章主要介紹了vue中v-if?和v-permission?共同使用的坑及解決方案的相關(guān)資料,需要的朋友可以參考下
    2023-07-07
  • 基于axios 解決跨域cookie丟失的問(wèn)題

    基于axios 解決跨域cookie丟失的問(wèn)題

    今天小編就為大家分享一篇基于axios 解決跨域cookie丟失的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2018-09-09

最新評(píng)論