溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶(hù)服務(wù)條款》

Vue中如何獲取DOM元素

發(fā)布時(shí)間:2022-12-27 10:17:39 來(lái)源:億速云 閱讀:98 作者:iii 欄目:web開(kāi)發(fā)

今天小編給大家分享一下Vue中如何獲取DOM元素的相關(guān)知識(shí)點(diǎn),內(nèi)容詳細(xì),邏輯清晰,相信大部分人都還太了解這方面的知識(shí),所以分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后有所收獲,下面我們一起來(lái)了解一下吧。

dom是一種文檔對(duì)象模型,同時(shí)也是用于html編程的接口,通過(guò)dom來(lái)操作頁(yè)面中的元素。DOM是HTML文檔的內(nèi)存中對(duì)象表示,它提供了使用JavaScript與網(wǎng)頁(yè)交互的方式。DOM是節(jié)點(diǎn)的層次結(jié)構(gòu)(或樹(shù)),其中document節(jié)點(diǎn)作為根。

什么是dom

dom是一種文檔對(duì)象模型,同時(shí)也是用于html編程的接口,通過(guò)dom來(lái)操作頁(yè)面中的元素。當(dāng)html頁(yè)面被實(shí)現(xiàn)加載的時(shí)候,瀏覽器會(huì)創(chuàng)建一個(gè)dom,給文檔提供了一種新的邏輯結(jié)構(gòu),并且可以改變內(nèi)容和結(jié)構(gòu)。

DOM稱(chēng)為文件對(duì)象模型(DocumentObjectModel,簡(jiǎn)稱(chēng)DOM),是W3C組織推薦的處理可擴(kuò)展置標(biāo)語(yǔ)言的標(biāo)準(zhǔn)編程接口

DOM是HTML文檔的內(nèi)存中對(duì)象表示,它提供了使用JavaScript與網(wǎng)頁(yè)交互的方式。DOM是節(jié)點(diǎn)的層次結(jié)構(gòu)(或樹(shù)),其中document節(jié)點(diǎn)作為根。

實(shí)際上DOM是以面向?qū)ο蟮姆绞絹?lái)描述的文檔模型。DOM定義了表示和修改文檔所需的對(duì)象和這些對(duì)象的行為和屬性以及這些對(duì)象之間的關(guān)系。

通過(guò)JavaScript,我們可以重構(gòu)整個(gè)HTML文檔。比如添加、移除、改變或重排頁(yè)面上的項(xiàng)目。

要改變頁(yè)面上的某個(gè)東西,JavaScript就需要獲得對(duì)HTML文檔中所有元素進(jìn)行訪(fǎng)問(wèn)的入口。這個(gè)入口,連同對(duì)HTML元素進(jìn)行添加、移動(dòng)、改變或移除的方法和屬性,都是通過(guò)文檔對(duì)象模型來(lái)獲得的。

什么是虛擬DOM

虛擬 DOM (Virtual DOM )這個(gè)概念相信大家都不陌生,從 React 到 Vue ,虛擬 DOM 為這兩個(gè)框架都帶來(lái)了跨平臺(tái)的能力(React-Native 和 Weex)

實(shí)際上它只是一層對(duì)真實(shí)DOM的抽象,以JavaScript 對(duì)象 (VNode 節(jié)點(diǎn)) 作為基礎(chǔ)的樹(shù),用對(duì)象的屬性來(lái)描述節(jié)點(diǎn),最終可以通過(guò)一系列操作使這棵樹(shù)映射到真實(shí)環(huán)境上

在Javascript對(duì)象中,虛擬DOM 表現(xiàn)為一個(gè) Object對(duì)象。并且最少包含標(biāo)簽名 (tag)、屬性 (attrs) 和子元素對(duì)象 (children) 三個(gè)屬性,不同框架對(duì)這三個(gè)屬性的名命可能會(huì)有差別

創(chuàng)建虛擬DOM就是為了更好將虛擬的節(jié)點(diǎn)渲染到頁(yè)面視圖中,所以虛擬DOM對(duì)象的節(jié)點(diǎn)與真實(shí)DOM的屬性一一照應(yīng)

在vue中同樣使用到了虛擬DOM技術(shù)

定義真實(shí)DOM

<div id="app">
    <p class="p">節(jié)點(diǎn)內(nèi)容</p>
    <h4>{{ foo }}</h4>
</div>

實(shí)例化vue

const app = new Vue({
    el:"#app",
    data:{
        foo:"foo"
    }
})

觀察render的render,我們能得到虛擬DOM

(function anonymous(
) {
	with(this){return _c('div',{attrs:{"id":"app"}},[_c('p',{staticClass:"p"},
					  [_v("節(jié)點(diǎn)內(nèi)容")]),_v(" "),_c('h4',[_v(_s(foo))])])}})

通過(guò)VNode,vue可以對(duì)這顆抽象樹(shù)進(jìn)行創(chuàng)建節(jié)點(diǎn),刪除節(jié)點(diǎn)以及修改節(jié)點(diǎn)的操作, 經(jīng)過(guò)diff算法得出一些需要修改的最小單位,再更新視圖,減少了dom操作,提高了性能。

Vue獲取DOM的幾種方法

雖然Vue實(shí)現(xiàn)了MVVM模型,將數(shù)據(jù)和表現(xiàn)進(jìn)行了分離,我們只需要更新數(shù)據(jù)就能使DOM同步更新,但是某些情況下,還是需要獲取DOM元素進(jìn)行操作(比如引入的某個(gè)庫(kù)要求傳入一個(gè)根dom元素作為根節(jié)點(diǎn),或者寫(xiě)一些自定義指令),本文主要介紹幾種在Vue中獲取DOM元素的方法。

使用DOM API直接找元素

<script>
	...
	mounted () {
		let elm = this.$el.querySelector('#id')
	}
</script>

這種方法足夠簡(jiǎn)單直觀,Vue組件在patch階段結(jié)束時(shí)會(huì)把this.$el賦值為掛載的根dom元素,我們可以直接使用$elquerySelector, querySelectorAll等方法獲取匹配的元素。

refs

<template>
	<div ref="bar">{{ foo }}</div>
	<MyAvatar ref="avatar" />
	...
</template>
<script>
	...
	mounted () {
		let foo = this.$refs['bar'] // 一個(gè)dom元素
		let avatar = this.$refs['avatar'] // 一個(gè)組件實(shí)例對(duì)象
	}
</script>

使用組件實(shí)例的$refs即可拿到組件上ref屬性對(duì)應(yīng)的元素。
如果ref屬性加在一個(gè)組件上,那么拿到的是這個(gè)組件的實(shí)例,否則拿到的就是dom元素了。

值得注意的是包含v-for循環(huán)模板指令的情況,其循環(huán)元素和子元素上ref屬性對(duì)應(yīng)的都是一個(gè)數(shù)組(就算動(dòng)態(tài)生成ref,也是數(shù)組):

<template>
	<div v-for="item in qlist" :key="item.id" ref="qitem">
		<h4>{{ item.title  }}</h4>
		<p ref="pinitem">{{ item.desc }}</p>
		<p :ref="'contact'+item.id">{{ item.contact }}</p>
	</div>
	...
</template>
<script>
	...
	data () {
		return {
			qlist: [
				{ id: 10032, title: 'abc', desc: 'aadfdcc', contact: 123 },
				{ id: 11031, title: 'def', desc: '--*--', contact: 856 },
				{ id: 20332, title: 'ghi', desc: '?/>,<{]', contact: 900 }
			]
		}
	},
	mounted () {
		let foo = this.$refs['qitem'] // 一個(gè)包含dom元素的數(shù)組
		let ps = this.$refs['pinitem'] // p元素是v-for的子元素,同樣是一個(gè)數(shù)組
		let contact1 = this.$refs['contact' + this.qlist[0].id] // 還是個(gè)數(shù)組
	}
</script>

關(guān)于這個(gè)的原因,可以從Vue關(guān)于ref處理的部分代碼得到:

function registerRef (vnode, isRemoval) {
  var key = vnode.data.ref;
  if (!isDef(key)) { return }

  var vm = vnode.context;
  // vnode如果有componentInstance表明是一個(gè)組件vnode,它的componentInstance屬性是其真實(shí)的根元素vm
  // vnode如果沒(méi)有componentInstance則不是組件vnode,是實(shí)際元素vnode,直接取其根元素
  var ref = vnode.componentInstance || vnode.elm;
  var refs = vm.$refs;
  if (isRemoval) {
    ...
  } else {
  	// refInFor是模板編譯階段生成的,它是一個(gè)布爾值,為true表明此vnode在v-for中
    if (vnode.data.refInFor) {
      if (!Array.isArray(refs[key])) {
        refs[key] = [ref]; // 就算元素唯一,也會(huì)被處理成數(shù)組
      } else if (refs[key].indexOf(ref) < 0) {
        // $flow-disable-line
        refs[key].push(ref);
      }
    } else {
      refs[key] = ref;
    }
  }
}

使用自定義指令

Vue提供了自定義指令,官方文檔給出了如下的使用方法,其中el就是dom元素的引用

Vue.directive('focus', {
  // 當(dāng)被綁定的元素插入到 DOM 中時(shí)……
  inserted: function (el) {
    // 聚焦元素
    el.focus()
  }
})

// 在模板中
<template>
	<input v-model="name" v-focus />
</template>

關(guān)于自定義指令,在一些組件庫(kù)和事件上報(bào)等場(chǎng)景下非常有用。

以上就是“Vue中如何獲取DOM元素”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家閱讀完這篇文章都有很大的收獲,小編每天都會(huì)為大家更新不同的知識(shí),如果還想學(xué)習(xí)更多的知識(shí),請(qǐng)關(guān)注億速云行業(yè)資訊頻道。

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI