Vue如何進(jìn)行數(shù)據(jù)代理
在了解了關(guān)于js當(dāng)中的Object.defineProperty()這個方法后,我們繼續(xù)對vue當(dāng)中的數(shù)據(jù)代理做一個基于現(xiàn)在的解析
建議觀看之前先了解下js當(dāng)中的Obejct.defineProperty()
了解如何代理
準(zhǔn)備工作
- 準(zhǔn)備一個容器,供vue實(shí)例對象指定
- 在實(shí)例對象當(dāng)中配置供頁面調(diào)用的數(shù)據(jù)(data)
- 測試頁面
<body> <!-- 準(zhǔn)備一個容器 --> <div class="subject"> <div>昵稱:{{name}}</div> <div>電話:{{phone}}</div> </div> </body> <script> new Vue({ el: '.subject', data: { name: 'wavesbright', phone:"134****2557" } }); </script>
查看VM
通過之前的復(fù)習(xí),我們知道,在vm這個實(shí)例對象當(dāng)中配置項(xiàng)data當(dāng)中的屬性,會掛載到vm上,供頁面調(diào)用而鼠標(biāo)懸停在二者身上,出現(xiàn)了 invoke property getter,說明什么?說明,vm上的name和phone,是通過defineProperty 添加上去的 === 做了數(shù)據(jù)代理
和誰做了數(shù)據(jù)代理?
當(dāng)你訪問 name 或者 phone的時候一定會調(diào)用get(getter),這個get 一定會從某個地方,將所需要的值進(jìn)行 返回什么地方? data嘛
var vm = new Vue({ el: '.subject', data: { name:'wavesbright' phone:"134****2557" } });
那你要對 name 和 phone 進(jìn)行修改的時候,那肯定要 調(diào)用set嘛如何確定呢?
get和set
確實(shí)有,在哪里呢,往下翻就可以看到
這不就是代理么
驗(yàn)證兩條線
vm當(dāng)中的name 與 phone 是 與data進(jìn)行數(shù)據(jù)綁定的
get
既然綁定了,那當(dāng)我訪問name變量的時候先調(diào)用getget 返回 data.name當(dāng)中配置的value值
驗(yàn)證過程
很簡單,直接修改data.name的值不就知道了
原圖
修改后
說明是綁定到一起的嘛,但我為什么不修改 vm.name的值去查看data是否發(fā)生改變了呢?
問題引出1
我們設(shè)計(jì)的data當(dāng)中的屬性,經(jīng)過vue的一系列操作最終掛載到了vue實(shí)例上,實(shí)現(xiàn)了數(shù)據(jù)綁定數(shù)據(jù)綁定是一個事實(shí),我們現(xiàn)在所做的是驗(yàn)證這個過程通過修改配置項(xiàng) data當(dāng)中的name屬性,頁面當(dāng)中確實(shí)發(fā)生了變化但是我現(xiàn)在想驗(yàn)證的是,我修改 vm.name的值的時候,data如何確定變化
用vm.data查看就能完成了,這不很簡單嘛?是嗎?
開國際玩笑哦,你data在全局定義了嗎?沒有吧?vm當(dāng)中為什么也沒有data呢?
set
解決方式1
定義一個全局的data不就行了
驗(yàn)證一下嘛,修改vue當(dāng)中的name屬性,data是否會發(fā)生變化
確實(shí)可以
問題衍生2
那么又有一個問題,我這個全局data是自己定義的,而正常構(gòu)建的vue實(shí)例對象可不會這么寫
但事實(shí)情況就是,我修改配置項(xiàng)data當(dāng)中的數(shù)據(jù),可以影響頁面,而修改頁面也可以影響data
我辛辛苦苦配置了一個data對象,交給了vm,vm如果不把我這個data存下來,那人家以后要用屬性去那里?。縱m一定會把這個data留下來。
這就說明一個問題,配置項(xiàng)data,一定在 構(gòu)建完成的這個實(shí)例對象vm身上,但是為什么找不到呢?
因?yàn)槿思医?vm._data
這個就不展開了,因?yàn)?vm當(dāng)中的data除了做數(shù)據(jù)代理,還有數(shù)據(jù)劫持
我們當(dāng)下只需要記住一點(diǎn),vm._data === data
驗(yàn)證set的過程
這是當(dāng)前頁面,現(xiàn)在我們要修改name屬性
修改成全大寫
分析過程
我們修改了vm.name的值一定調(diào)用了 set函數(shù),拿到這個value值并且將這個 value值賦給了vm._data(data)
圖文解析
第一部分
一切的一切都是因?yàn)殚_頭寫了這段代碼
var vm = new Vue({ el: '.subject', data: { name:'wavesbright' phone:"134****2557" } });
緊隨其后,馬上就給我們創(chuàng)建了一個vue的實(shí)例對象
然后,vue開始為vm這個實(shí)例對象準(zhǔn)備一些東西(屬性)
重點(diǎn),data來了,完全來自于上方的配置項(xiàng)data
截止到目前來說,沒有數(shù)據(jù)代理的存在。我們所寫的data,就是單純的進(jìn)行了一次賦值,然后給了下劃線data(_data)
第二部分
實(shí)際上,vue做到這一步已經(jīng)差不多了,代碼也是可以寫下去的
但是,請問,目前vm身上,有name嗎,沒有
但是我能拿到name的值嗎?可以的,因?yàn)槲矣?_data
<body> <!--準(zhǔn)備一個容器--> <div class="subject"> <div>昵稱:{{_data.name}}</div> <div>電話:{{_data.phone}}</div> </div> </body> <script> /* var data = {... var vm = new Vue({ el:'.subject', data:{ name:'wavesbright' phone:"134****2557" } }); </script>
一樣可以拿到name和phone的值
因?yàn)?,vm這個對象身上的所有屬性,在模板上面都能夠直接使用
但是這樣寫,那不是直接崩潰,創(chuàng)建一個變量就需要 _data一次,vue在這里做了一個很棒的操作
也就是數(shù)據(jù)代理
第三部分
vm在自己身上創(chuàng)建了一個變量name什么方式創(chuàng)建的?defineProperty通過get拿到vm自身上的_data.name的值修改數(shù)據(jù)的時候通過set,獲取value,然后再將_data當(dāng)中的屬性進(jìn)行修改完成了數(shù)據(jù)代理,雙向綁定
為什么要將data當(dāng)中的數(shù)據(jù)放在vm身上一份呢(_data)
就是為了讓你編碼的時候更方便(不至于每次都是 _data.xxx)
總結(jié)
- vue中的數(shù)據(jù)代理
- 通過vm對象 來 代理 data對象(配置項(xiàng))中的屬性操作(get/set)
- Vue中數(shù)據(jù)代理的好處
- 更加方便操作data中的數(shù)據(jù)(_data.xxx)
- 基本原理
通過Object.defineProperty()將data配置項(xiàng)當(dāng)中的所有屬性配置到vm對象上
為每一個添加到vm上的屬性,指定一個get和set函數(shù)(getter/setter)
在getter/setter內(nèi)部去操作(讀/寫),data中對應(yīng)的屬性
展開_data
思考
老師不讓展開是對的
因?yàn)槿绻凑罩暗睦斫?,這個符號代表什么 (...) 代表數(shù)據(jù)代理
這樣容易引起理解誤區(qū),,這里實(shí)際上并不是數(shù)據(jù)代理,而是做了一個數(shù)據(jù)劫持
我希望看到的 _data的展開內(nèi)容是什么?是這樣的
data:{ name:'wavesbright' phone:"134****2557" }
實(shí)際上并不是
vue的承諾
只要你敢修改data當(dāng)中的屬性值,我就敢在頁面當(dāng)中 {{property}}一起發(fā)生變化
- 當(dāng)name的值發(fā)生了改變,最終影響到的是誰 === _data.name
- 那么頁面元素是怎么同步進(jìn)行修改的?
- vue是不是必須要知道,name這里發(fā)生了改變,他需要做什么 === 監(jiān)聽
- 經(jīng)歷了一系列變動后,完成了小小的升級,最終達(dá)成響應(yīng)式操作
到此這篇關(guān)于vue如何進(jìn)行數(shù)據(jù)代理的文章就介紹到這了,更多相關(guān)vue數(shù)據(jù)代理內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
vue在手機(jī)中通過本機(jī)IP地址訪問webApp的方法
這篇文章主要介紹了vue在手機(jī)中通過本機(jī)IP地址訪問webApp的方法,需要的朋友可以參考下2018-08-08Vue.js 遞歸組件實(shí)現(xiàn)樹形菜單(實(shí)例分享)
本文主要對介紹利用Vue.js 的遞歸組件,實(shí)現(xiàn)了一個最基本的樹形菜單。具有很好的參考價值,下面就跟著小編一起來看下吧2016-12-12Vue+Java+Base64實(shí)現(xiàn)條碼解析的示例
這篇文章主要介紹了Vue+Java+Base64實(shí)現(xiàn)條碼解析的示例,幫助大家實(shí)現(xiàn)條碼解析,感興趣的朋友可以了解下2020-09-09vue項(xiàng)目實(shí)現(xiàn)表單登錄頁保存賬號和密碼到cookie功能
這篇文章主要介紹了vue項(xiàng)目實(shí)現(xiàn)表單登錄頁保存賬號和密碼到cookie功能,非常不錯,具有一定的參考借鑒價值,需要的朋友可以參考下2018-08-08vue實(shí)現(xiàn)三級聯(lián)動動態(tài)菜單
這篇文章主要為大家詳細(xì)介紹了vue實(shí)現(xiàn)三級聯(lián)動動態(tài)菜單,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-04-04vue導(dǎo)入.md文件的步驟(markdown轉(zhuǎn)HTML)
這篇文章主要介紹了vue導(dǎo)入.md文件的步驟(markdown轉(zhuǎn)HTML),幫助大家更好的理解和使用vue框架,感興趣的朋友可以了解下2020-12-12