Vue數據代理的原理和實現
Object.defineProperty
defineProperty方法會直接在一個對象上定義一個新屬性,或者修改另一個對象的現有屬性,并返回此對象,通常使用 get 進行讀取,用 set 進行修改。
注意:defineProperty定義的屬性是不能進行枚舉(不能參與遍歷)的
<body> <script> let person = { name:'張三', sex:'男' } Object.defineProperty(person,'age',{ value:18 }) console.log(Object.keys(person)); console.log(person); </script> </body>
當然,defineProperty內部的屬性我們自己控制,可以根據需求進行一定修改,如下:
Object.defineProperty(person,'age',{ value:18, enumerable:true, //控制屬性是否可以枚舉,默認值是false writable:true, //控制屬性是否可以被修改,默認值是false configurable:true, //控制屬性是否可以被刪除,默認值是false })
definedProperty最重要的點就是get和set了,如下:
<script> let number = 18 let person = { name:'張三', sex:'男' } Object.defineProperty(person,'age',{ // 當有人讀取person的age屬性時,get函數(getter)就會被調用,且返回值就是age值 get(){ console.log('有人讀取了age屬性'); return number }, // 當有人修改person的age屬性時,set函數(setter)就會被調用,且會收到修改的具體值 set(value){ console.log('有人修改了age屬性,且值是',value); number = value } }) </script>
根據上文的簡述,我們理解數據代理就是:通過一個對象代理對另一個對象中屬性的操作(讀/寫)
<script> let obj = {x:100} let obj1 = {y:200} Object.defineProperty(obj1,'x',{ get(){ return obj.x }, set(value){ obj.x = value } }) </script>
那么在Vue中如何應用數據代理呢
<body> <div id="root"> <h2>姓名:{{name}}</h2> <h2>年齡:{{age}}</h2> </div> <script src="/Vue.js/vue.js"></script> <script> Vue.config.productionTip = false; //阻止 vue 在啟動時生成生產提示 new Vue({ el:'#root', data:{ name:'張三', age:18 } }) </script> </body>
可以看出 vm 身上有我們data里面的name和age屬性,所以當我們訪問data上面的name或age的時候,getter開始工作;如果通過vm去修改這個name或age時,setter開始工作。即在data里面的數據是有自己的get和set,如下:
get的實現:很簡單,當我們修改data.name的時候,我們在查看name的時候,name的值就是data.name的值,如下:
set的實現:當我們進行修改name的時候,直接在控制臺修改name的值。
name的值的的確確是被修改了也渲染到頁面上去了,但我們怎么保證是data.name里面的name也被真真修改了呢?現在分析一下,data里面的name到底改沒改。
注意:我們不能直接在控制臺輸入data.name來查看,因為data僅僅是Vue里面配置項的一個屬性,并不是全局變量,是不能進行訪問的,如果訪問會報下面這樣的錯誤。
那么我們如何拿到data里面的name呢?在Vue中vm會把data里面的數據存在 _data 里面,所以說vm._data的data就是我們存放數據的data,那么如何驗證呢?既然我們不能訪問到Vue里面的data,那么我們把Vue里面的data的數據給寫到全局變量里面,然后Vue再引用全局上的data,這樣我們就可以驗證,Vue自帶的 _data 的數據是不是和Vue實例里面的data數據相等。
<script> Vue.config.productionTip = false; //阻止 vue 在啟動時生成生產提示 let data = { name:'張三', age:18 } const vm = new Vue({ data }) vm.$mount('#root') // 接下來我們驗證 vm._data = options.data = data 是不是true;options.data就是Vue里面配置項的data;data就是我們定義在外面的data console.log(Boolean(vm._data = vm.data = data)); //true </script>
數據代理說白了就是把data里面的數據放一份到 vm 上面,目的就是為了當編碼更方便。
總結
Vue中的數據代理:
通過vm對象來代理data對象中屬性的操作(讀/寫)
Vue中數據代理的好處:
更加方便的操作data中的數據
基本原理:
通過Object.defineProperty()把data對象上所有屬性添加到vm上。為每個添加到vm上的屬性都指定一個getter/setter。在getter/setter內部去操作(讀/寫)data中對應的屬性。
到此這篇關于Vue數據代理的原理和實現的文章就介紹到這了,更多相關Vue數據代理內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
vue style width a href動態(tài)拼接問題的解決
這篇文章主要介紹了vue style width a href動態(tài)拼接問題的解決,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-08-08基于Vue sessionStorage實現保留搜索框搜索內容
這篇文章主要介紹了基于Vue sessionStorage實現保留搜索框搜索內容,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下2020-06-06實例詳解vue.js淺度監(jiān)聽和深度監(jiān)聽及watch用法
這篇文章主要介紹了vue.js淺度監(jiān)聽和深度監(jiān)聽及watch用法,本文通過實例代碼給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友參考下吧2018-08-08