一文詳解Vue的響應式原則與雙向數據綁定
反應性原則
它是 Vue.js 的核心特性之一,一個數據驅動的視圖,我們修改數據視圖來響應更新,非常優(yōu)雅。
Vue2.x 使用 Object.defineProperty() 實現,而 Vue3.x 使用 Proxy 實現。 我們先來看看2.x的實現。
Object.defineProperty(obj, key, { enumerable: true, configurable: true, get: function getter () { return obj[key]; }, set: function setter (newVal) { ... } })
我們通過Object.defineProperty給對象obj添加屬性,可以設置對象屬性的getter和setter函數。
之后,我們每通過點語法獲取一個屬性,就會執(zhí)行這里的getter函數。 在這個函數中,我們會將調用這個屬性的依賴收集到一個集合中; 當我們給屬性賦值時,這個定義就會被觸發(fā)。 setter函數,在輔助函數中,會通知集合中的依賴更新,讓數據變化驅動視圖變化。
3.x的核心思想和2.x一樣,只是在數據劫持上使用了Proxy而不是Object.defineProperty,但是在處理數組和響應式處理新屬性時Proxy比Object.defineProperty更方便 .
let nObj=new Proxy(obj,{ get: function (target, propKey, receiver) { console.log(`getting ${propKey}!`); return Reflect.get(target, propKey, receiver); }, set: function (target, propKey, value, receiver) { console.log(`setting ${propKey}!`); return Reflect.set(target, propKey, value, receiver); } })
Vue響應式原理的實現細節(jié)相信大部分人已經很熟悉了,這里不再贅述。
雙向數據綁定
雙向數據綁定通常是指我們使用的 v-model 指令的實現。 它是 Vue 的一個特性,也可以說是輸入事件和值的語法糖。 Vue 通過 v-model 指令為組件添加輸入事件處理和值屬性賦值。
<template> <input v-model='localValue'/> </template>
上面的組件等價于下面的代碼。
<template> <input @input='onInput' :value='localValue' /> <span>{{localValue}}</span> </template> <script> export default{ data(){ return { localValue:'', } }, methods:{ onInput(v){ this.localValue=v.target.value; console.log(this.localValue) } } } </script>
因此,當我們修改輸入框的值時,我們通過v-model綁定的值也會同步修改。 基于以上原理,我們可以輕松實現一個雙向數據綁定組件。
v-model實踐
首先,我們定義一個Vue組件:
<tempalte> <div class="count" @click="addCount">click me {{value}}</div> </template> <script> export default{ props:{ value:{ type:Number, default:0 } }, watch:{ value(v){ this.localvalue=v; } }, methods:{ addCount(){ this.localvalue++; this.$emit('input',this.localvalue); } }, data(){ return{ localvalue:0 } }, created(){ this.localvalue=this.value; } } </script>
上面的組件指定我們在 props 中添加 value 屬性,并在 value 更新時觸發(fā) input 事件。 在創(chuàng)建的 hook 和 watch 中對 localvalue 的賦值是將父組件的狀態(tài)同步到子組件。
通過上面的組件定義,我們可以使用 v-model 指令對組件進行雙向數據綁定。
<template> <add-one v-model="count"></add-one> <span>The parent component{{count}}</span> </tempalte> <script> export default{ data() { return { count: 0, }; }, methods: { }, created(){ } } </script>
以下是實際效果。
當然,我們也可以不使用 value 和 input 事件的組合。 為了讓組件的定義更加語義化,我們還可以自定義屬性和事件,實現雙向綁定。 我們可以在組件的模型選項中設置值和事件。 如下:
export default{ model:{ value:'count', event:'change' }, props:{ count:{ type:Number, default:0 } }, methods:{ addCount(){ this.localvalue++; this.$emit('change',this.localvalue); } }, }
由上述組件定義。
<add-one v-model="count"></add-one>
相當于:
<template> <add-one @change='onChange' :count='count'></add-one> <span>{{count}}</span> </template> <script> export default{ data(){ return { count:0, } }, methods:{ onChange(v){ this.count=v; console.log(this.count) } } } </script>
只是v-model指令幫我們做了上面的事件添加、屬性綁定和狀態(tài)同步操作。
到此這篇關于一文詳解Vue的響應式原則與雙向數據綁定的文章就介紹到這了,更多相關Vue雙向數據綁定內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!