dom是一種文件物件模型,同時也是用於html程式設計的接口,透過dom來操作頁面中的元素。 DOM是HTML文件的記憶體中物件表示,它提供了使用JavaScript與網頁互動的方式。 DOM是節點的層次結構(或樹),其中document節點為根。
本教學操作環境:windows7系統、vue3版,DELL G3電腦。
什麼是dom
dom是一種文檔物件模型,同時也是用於html程式設計的接口,透過dom來操作頁面中的元素。當html頁面被實作載入的時候,瀏覽器會創建一個dom,給了文件一個新的邏輯結構,並且可以改變內容和結構。
DOM稱為檔案物件模型(DocumentObjectModel,簡稱DOM),是W3C組織推薦的處理可擴充置標語言的標準程式介面
DOM是HTML文件的記憶體中物件表示,它提供了使用JavaScript與網頁互動的方式。 DOM是節點的層次結構(或樹),其中document節點為根。
實際上DOM是以物件導向的方式來描述的文檔模型。 DOM定義了表示和修改文件所需的物件和這些物件的行為和屬性以及這些物件之間的關係。
透過JavaScript,我們可以重構整個HTML文件。例如新增、移除、變更或重排頁面上的項目。
要改變頁面上的某個東西,JavaScript就需要取得對HTML文件中所有元素進行存取的入口。這個入口,連同對HTML元素進行添加、移動、改變或移除的方法和屬性,都是透過文件物件模型來獲得的。
什麼是虛擬DOM
虛擬DOM (Virtual DOM )這個概念相信大家都不陌生,從React 到Vue ,虛擬DOM 為這兩個框架都帶來了跨平台的能力(React-Native 和Weex)
其實它只是一層對真實DOM的抽象,以JavaScript 物件(VNode 節點) 作為基礎的樹,用物件的屬性來描述節點,最終可以透過一系列操作使這棵樹映射到真實環境上
在Javascript物件中,虛擬DOM 表現為一個Object物件。且最少包含標籤名(tag)、屬性(attrs) 和子元素物件(children) 三個屬性,不同框架對這三個屬性的名命可能會有差別
建立虛擬DOM就是為了更好將虛擬的節點渲染到頁面視圖中,所以虛擬DOM物件的節點與真實DOM的屬性一一照應
在vue中同樣使用到了虛擬DOM技術
定義真實DOM
<div id="app"> <p class="p">节点内容</p> <h3>{{ foo }}</h3> </div>
實例化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("节点内容")]),_v(" "),_c('h3',[_v(_s(foo))])])}})
透過VNode,vue可以對這顆抽象樹進行建立節點,刪除節點以及修改節點的操作, 經過diff演算法得出一些需要修改的最小單位,再更新視圖,減少了dom操作,提高了效能。
Vue取得DOM的幾種方法
#雖然Vue實作了MVVM模型,將資料和表現進行了分離,我們只需要更新資料就能使DOM同步更新,但是某些情況下,還是需要取得DOM元素進行操作(例如引入的某個庫要求傳入一個根dom元素作為根節點,或寫一些自訂指令),本文主要介紹幾種在Vue中取得DOM元素的方法。
<script> ... mounted () { let elm = this.$el.querySelector('#id') } </script>
這個方法夠簡單直觀,Vue元件在patch階段結束時會把 this.$el
賦值為掛載的根dom元素,我們可以直接使用$el
的querySelector, querySelectorAll
等方法來取得相符的元素。
<template> <div ref="bar">{{ foo }}</div> <MyAvatar ref="avatar" /> ... </template> <script> ... mounted () { let foo = this.$refs['bar'] // 一个dom元素 let avatar = this.$refs['avatar'] // 一个组件实例对象 } </script>
使用元件實例的$refs
即可拿到元件上ref
屬性對應的元素。
如果ref屬性加在一個元件上,那麼拿到的是這個元件的實例,否則拿到的就是dom元素了。
值得注意的是包含v-for
循環模板指令的情況,其循環元素和子元素上ref
屬性對應的都是一個陣列(就算動態生成ref,也是陣列):
<template> <div v-for="item in qlist" :key="item.id" ref="qitem"> <h3>{{ item.title }}</h3> <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'] // 一个包含dom元素的数组 let ps = this.$refs['pinitem'] // p元素是v-for的子元素,同样是一个数组 let contact1 = this.$refs['contact' + this.qlist[0].id] // 还是个数组 } </script>
關於這個的原因,可以從Vue關於ref處理的部分程式碼得到:
function registerRef (vnode, isRemoval) { var key = vnode.data.ref; if (!isDef(key)) { return } var vm = vnode.context; // vnode如果有componentInstance表明是一个组件vnode,它的componentInstance属性是其真实的根元素vm // vnode如果没有componentInstance则不是组件vnode,是实际元素vnode,直接取其根元素 var ref = vnode.componentInstance || vnode.elm; var refs = vm.$refs; if (isRemoval) { ... } else { // refInFor是模板编译阶段生成的,它是一个布尔值,为true表明此vnode在v-for中 if (vnode.data.refInFor) { if (!Array.isArray(refs[key])) { refs[key] = [ref]; // 就算元素唯一,也会被处理成数组 } else if (refs[key].indexOf(ref) < 0) { // $flow-disable-line refs[key].push(ref); } } else { refs[key] = ref; } } }
Vue提供了自訂指令,官方文件給出瞭如下的使用方法,其中el
就是dom元素的引用
Vue.directive('focus', { // 当被绑定的元素插入到 DOM 中时…… inserted: function (el) { // 聚焦元素 el.focus() } }) // 在模板中 <template> <input v-model="name" v-focus /> </template>
關於自訂指令,在一些元件庫和事件上報等場景下非常有用。
以上是vue dom是什麼意思啊的詳細內容。更多資訊請關注PHP中文網其他相關文章!