在react中是單向數據綁定,而Vue.js 最顯著的特點就是響應式和數據驅動,也就是將Model和View進行單向綁定或者雙向綁定。
單向綁定:把Model綁定到View,當我們用JavaScript代碼更新Model時,View就會自動更新。因此,我們不需要進行額外的DOM操作,只需要進行Model的操作就可以實現視圖的聯動更新。
雙向綁定:把Model綁定到View的同時也將View綁定到Model上,這樣就既可以通過更新Model來實現View的自動更新,也可以通過更新View來實現Model數據的更新。所以,當我們用JavaScript代碼更新Model時,View就會自動更新,反之,如果用戶更新了View,Model的數據也自動被更新了。
1.單向綁定
1.1插值形式
插值形式就是{{data}}的形式,它使用的是單向綁定。
單向數據綁定的實現思路:
① 所有數據只有一份
② 一旦數據變化,就去更新頁面(只有data-->DOM,沒有DOM-->data)
③ 若用戶在頁面上做了更新,就手動收集(雙向綁定是自動收集),合並到原有的數據中。
<body> <div id="vm"> <p>Hello, {{name}}!</p> <p>You are {{age}} years old!</p> </div> </body> <script src="https://cdn.jsdelivr.net/npm/vue"></script> <script type="text/javascript"> var vm = new Vue({ el: '#vm', data: { name: 'DroidMind', age: 18 } }); </script>
打開瀏覽器console,在控制台輸入vm.name = 'Bob',執行上述代碼,可以觀察到頁面立刻發生了變化,原來的Hello,DroidMind!自動變成了Hello, Bob!。Vue作為MVVM框架會自動監聽Model的任何變化,在Model數據變化時,更新View的顯示。這種Model到View的綁定就是單向綁定。
1.2v-bind形式
<body> <div id="vm"> <p v-bind:class="classed">Hello, {{name}}!</p> </div> </body> <script src="https://cdn.jsdelivr.net/npm/vue"></script> <script type="text/javascript"> var vm = new Vue({ el: '#vm', data: { name: 'DroidMind', classed: 'red' } }); </script> <style> .red { background: red; } .blue { background: blue; } </style>
vm.classed的初始值為red,此時<p>的樣式屬性對應的是.red,此時背景就為紅色,我們可以通過在瀏覽器的控制台輸入vm.classed='bule',此時背景就自動變成了藍色。可以看到通過對class屬性進行綁定我們就可以動態的改變class對應的樣式,這個都是通過Model的操作完成的,沒有設置任何的DOM操作。
2.雙向綁定
v-model形式
數據的雙向綁定是vue實現的一大功能。
使用v-model指令,實現視圖和數據的雙向綁定。
所謂雙向綁定,指的是vue實例中的data與其渲染的DOM元素的內容保持一致,無論誰被改變,另一方會相應的更新為相同的數據。這是通過設置屬性訪問器實現的。
v-model主要用在表單的input輸入框,完成視圖和數據的雙向綁定。
v-model只能用在"input、select、textarea"這些表單元素上。
雙向綁定的缺點:不知道data什么時候變了,也不知道是誰變了,變化后也不會通知,當然可以watch來監聽data的變化,但這復雜,還不如單向綁定。
<body> <form id="vm" action="#"> <p><input v-model="email"></p> <p><input v-model="name"></p> </form> </body> <script src="https://cdn.jsdelivr.net/npm/vue"></script> <script type="text/javascript"> var vm = new Vue({ el: '#vm', data: { email: '', name: '' } }); </script>
我們可以在表單中輸入內容,然后在瀏覽器console中用vm.$data查看Model的內容,也可以用vm.name查看Model的name屬性,它的值和FORM表單對應的<input>是一致的。如果在瀏覽器console中用JavaScript更新Model,例如,執行vm.name='Bob',表單對應的<input>內容就會立刻更新。可以看到通過v-model實現了表單數據和Model數據的雙向綁定。
v-model 在內部為不同的輸入元素使用不同的 property 並拋出不同的事件,實際只是語法糖,所以vue跟react一樣是單向綁定:
- text 和 textarea 元素使用
valueproperty 和input事件; - checkbox 和 radio 使用
checkedproperty 和change事件; - select 字段將
value作為 prop 並將change作為事件。
3.狀態管理
其實無論是vue還是react其實還是提倡單向數據流去管理狀態,這一點在vuex和redux狀態管理器上體現的很明顯。
“單向數據流”理念的極簡示意:

state:驅動應用的數據源。view:以聲明方式將 state 映射到視圖 。 actions:響應在 view 上的用戶輸入導致的狀態變化
3.1 單向數據流過程:
簡單的單向數據流(unidirectional data flow)是指用戶訪問View,View發出用戶交互的Action,在Action里對state進行相應更新。state更新后會觸發View更新頁面的過程。這樣數據總是清晰的單向進行流動,便於維護並且可以預測。
3.2 vuex和redux解決什么問題:
雖然vue和react框架本身有自己狀態管理,當我們的應用遇到多個組件共享狀態時,單向數據流的簡潔性很容易被破壞:
(1)多個視圖依賴於同一狀態
(2)來自不同視圖的行為需要變更同一狀態
對於問題一,傳參的方法對於多層嵌套的組件將會非常繁瑣,並且對於兄弟組件間的狀態傳遞無能為力。
對於問題二,我們經常會采用父子組件直接引用或者通過事件來變更和同步狀態的多份拷貝。以上的這些模式非常脆弱,通常會導致無法維護的代碼。
因此,我們為什么不把組件的共享狀態抽取出來,以一個全局單例模式管理呢?在這種模式下,我們的組件樹構成了一個巨大的“視圖”,不管在樹的哪個位置,任何組件都能獲取狀態或者觸發行為!
另外,通過定義和隔離狀態管理中的各種概念並強制遵守一定的規則,我們的代碼將會變得更結構化且易維護。
