Vue數(shù)據(jù)代理的原理和實(shí)現(xiàn)
Object.defineProperty
defineProperty方法會(huì)直接在一個(gè)對(duì)象上定義一個(gè)新屬性,或者修改另一個(gè)對(duì)象的現(xiàn)有屬性,并返回此對(duì)象,通常使用 get 進(jìn)行讀取,用 set 進(jìn)行修改。
注意:defineProperty定義的屬性是不能進(jìn)行枚舉(不能參與遍歷)的
<body>
<script>
let person = {
name:'張三',
sex:'男'
}
Object.defineProperty(person,'age',{
value:18
})
console.log(Object.keys(person));
console.log(person);
</script>
</body>
當(dāng)然,defineProperty內(nèi)部的屬性我們自己控制,可以根據(jù)需求進(jìn)行一定修改,如下:
Object.defineProperty(person,'age',{
value:18,
enumerable:true, //控制屬性是否可以枚舉,默認(rèn)值是false
writable:true, //控制屬性是否可以被修改,默認(rèn)值是false
configurable:true, //控制屬性是否可以被刪除,默認(rèn)值是false
})definedProperty最重要的點(diǎn)就是get和set了,如下:
<script>
let number = 18
let person = {
name:'張三',
sex:'男'
}
Object.defineProperty(person,'age',{
// 當(dāng)有人讀取person的age屬性時(shí),get函數(shù)(getter)就會(huì)被調(diào)用,且返回值就是age值
get(){
console.log('有人讀取了age屬性');
return number
},
// 當(dāng)有人修改person的age屬性時(shí),set函數(shù)(setter)就會(huì)被調(diào)用,且會(huì)收到修改的具體值
set(value){
console.log('有人修改了age屬性,且值是',value);
number = value
}
})
</script>
根據(jù)上文的簡(jiǎn)述,我們理解數(shù)據(jù)代理就是:通過(guò)一個(gè)對(duì)象代理對(duì)另一個(gè)對(duì)象中屬性的操作(讀/寫(xiě))
<script>
let obj = {x:100}
let obj1 = {y:200}
Object.defineProperty(obj1,'x',{
get(){
return obj.x
},
set(value){
obj.x = value
}
})
</script>那么在Vue中如何應(yīng)用數(shù)據(jù)代理呢
<body>
<div id="root">
<h2>姓名:{{name}}</h2>
<h2>年齡:{{age}}</h2>
</div>
<script src="/Vue.js/vue.js"></script>
<script>
Vue.config.productionTip = false; //阻止 vue 在啟動(dòng)時(shí)生成生產(chǎn)提示
new Vue({
el:'#root',
data:{
name:'張三',
age:18
}
})
</script>
</body>
可以看出 vm 身上有我們data里面的name和age屬性,所以當(dāng)我們?cè)L問(wèn)data上面的name或age的時(shí)候,getter開(kāi)始工作;如果通過(guò)vm去修改這個(gè)name或age時(shí),setter開(kāi)始工作。即在data里面的數(shù)據(jù)是有自己的get和set,如下:

get的實(shí)現(xiàn):很簡(jiǎn)單,當(dāng)我們修改data.name的時(shí)候,我們?cè)诓榭磏ame的時(shí)候,name的值就是data.name的值,如下:

set的實(shí)現(xiàn):當(dāng)我們進(jìn)行修改name的時(shí)候,直接在控制臺(tái)修改name的值。

name的值的的確確是被修改了也渲染到頁(yè)面上去了,但我們?cè)趺幢WC是data.name里面的name也被真真修改了呢?現(xiàn)在分析一下,data里面的name到底改沒(méi)改。
注意:我們不能直接在控制臺(tái)輸入data.name來(lái)查看,因?yàn)閐ata僅僅是Vue里面配置項(xiàng)的一個(gè)屬性,并不是全局變量,是不能進(jìn)行訪問(wèn)的,如果訪問(wèn)會(huì)報(bào)下面這樣的錯(cuò)誤。

那么我們?nèi)绾文玫絛ata里面的name呢?在Vue中vm會(huì)把data里面的數(shù)據(jù)存在 _data 里面,所以說(shuō)vm._data的data就是我們存放數(shù)據(jù)的data,那么如何驗(yàn)證呢?既然我們不能訪問(wèn)到Vue里面的data,那么我們把Vue里面的data的數(shù)據(jù)給寫(xiě)到全局變量里面,然后Vue再引用全局上的data,這樣我們就可以驗(yàn)證,Vue自帶的 _data 的數(shù)據(jù)是不是和Vue實(shí)例里面的data數(shù)據(jù)相等。
<script>
Vue.config.productionTip = false; //阻止 vue 在啟動(dòng)時(shí)生成生產(chǎn)提示
let data = {
name:'張三',
age:18
}
const vm = new Vue({
data
})
vm.$mount('#root')
// 接下來(lái)我們驗(yàn)證 vm._data = options.data = data 是不是true;options.data就是Vue里面配置項(xiàng)的data;data就是我們定義在外面的data
console.log(Boolean(vm._data = vm.data = data)); //true
</script>數(shù)據(jù)代理說(shuō)白了就是把data里面的數(shù)據(jù)放一份到 vm 上面,目的就是為了當(dāng)編碼更方便。
總結(jié)
Vue中的數(shù)據(jù)代理:
通過(guò)vm對(duì)象來(lái)代理data對(duì)象中屬性的操作(讀/寫(xiě))
Vue中數(shù)據(jù)代理的好處:
更加方便的操作data中的數(shù)據(jù)
基本原理:
通過(guò)Object.defineProperty()把data對(duì)象上所有屬性添加到vm上。為每個(gè)添加到vm上的屬性都指定一個(gè)getter/setter。在getter/setter內(nèi)部去操作(讀/寫(xiě))data中對(duì)應(yīng)的屬性。
到此這篇關(guān)于Vue數(shù)據(jù)代理的原理和實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)Vue數(shù)據(jù)代理內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Electron進(jìn)程間通信的實(shí)現(xiàn)
本文主要介紹了Electron進(jìn)程間通信的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-05-05
Vuejs第九篇之組件作用域及props數(shù)據(jù)傳遞實(shí)例詳解
這篇文章主要介紹了Vuejs第九篇之組件作用域及props數(shù)據(jù)傳遞實(shí)例詳解的相關(guān)資料,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2016-09-09
基于ElementUI實(shí)現(xiàn)v-tooltip指令的示例代碼
文本溢出隱藏并使用tooltip 提示的需求,相信在平時(shí)的開(kāi)發(fā)中會(huì)經(jīng)常遇到,常規(guī)做法一般是使用 elementui 的 el-tooltip 組件,在每次組件更新的時(shí)候去獲取元素的寬度/高度判斷是否被隱藏,本文給大家介紹了基于ElementUI實(shí)現(xiàn)v-tooltip指令,需要的朋友可以參考下2024-09-09
解決vue scoped html樣式無(wú)效的問(wèn)題
這篇文章主要介紹了解決vue scoped html樣式無(wú)效的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-10-10
vue style width a href動(dòng)態(tài)拼接問(wèn)題的解決
這篇文章主要介紹了vue style width a href動(dòng)態(tài)拼接問(wèn)題的解決,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-08-08
基于Vue sessionStorage實(shí)現(xiàn)保留搜索框搜索內(nèi)容
這篇文章主要介紹了基于Vue sessionStorage實(shí)現(xiàn)保留搜索框搜索內(nèi)容,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-06-06
關(guān)于el-scrollbar滾動(dòng)條初始化不顯示的問(wèn)題及解決
這篇文章主要介紹了關(guān)于el-scrollbar滾動(dòng)條初始化不顯示的問(wèn)題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-08-08
實(shí)例詳解vue.js淺度監(jiān)聽(tīng)和深度監(jiān)聽(tīng)及watch用法
這篇文章主要介紹了vue.js淺度監(jiān)聽(tīng)和深度監(jiān)聽(tīng)及watch用法,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友參考下吧2018-08-08

