關(guān)于vue雙向綁定帶來的問題及解決
vue雙向綁定帶來的問題
問題場景
查詢完表格數(shù)據(jù)后 通過作用域插槽,將該行數(shù)據(jù)傳到修改頁面(定義了個(gè)新對象存儲(chǔ)數(shù)據(jù)),但是由于數(shù)據(jù)雙向綁定,修改這個(gè)新對象的值,會(huì)影響到最初查詢表格獲取的值
如下
this.editForm = row
解決方案
方法1:通過json之間的解析,深拷貝創(chuàng)建一個(gè)與row無綁定關(guān)聯(lián)的臨時(shí)對象,再賦值給editForm
this.editForm = JSON.parse(JSON.stringify(row))
方法2:使用…展開運(yùn)算符
this.editForm = {...this.editForm,...row}
方法3:$set也不會(huì)影響原數(shù)據(jù),但只能操作單個(gè)數(shù)據(jù),在上述場景可能不太適用(屬性多久麻煩了)
this.$set(this.editForm,'roleName',row.roleName) this.$set(this.editForm,'roleDesc',row.roleDesc)
這樣就不會(huì)影響到最初的row啦!
vue雙向綁定的原理總結(jié)
MVVM
視圖模型雙向綁定,是Model-View-ViewModel的縮寫,也就是把MVC中的Controller演變成ViewModel。Model層代表數(shù)據(jù)模型,View代表UI組件,ViewModel是View和Model層的橋梁,數(shù)據(jù)會(huì)綁定到viewModel層并自動(dòng)將數(shù)據(jù)渲染到頁面中,視圖變化的時(shí)候會(huì)通知viewModel層更新數(shù)據(jù)。以前是操作DOM結(jié)構(gòu)更新視圖,現(xiàn)在是數(shù)據(jù)驅(qū)動(dòng)視圖。
優(yōu)點(diǎn):
1.低耦合。視圖(View)可以獨(dú)立于Model變化和修改,一個(gè)Model可以綁定到不同的View上,當(dāng)View變化的時(shí)候Model可以不變化,當(dāng)Model變化的時(shí)候View也可以不變;
2.可重用性。你可以把一些視圖邏輯放在一個(gè)Model里面,讓很多View重用這段視圖邏輯。
3.獨(dú)立開發(fā)。開發(fā)人員可以專注于業(yè)務(wù)邏輯和數(shù)據(jù)的開發(fā)(ViewModel),設(shè)計(jì)人員可以專注于頁面設(shè)計(jì)。
4.可測試。
數(shù)據(jù)(model)變化主動(dòng)觸發(fā)ui(view)變化,同時(shí)ui(view)變化主動(dòng)觸發(fā)數(shù)據(jù)(model)變化,當(dāng)然這里的ui變化指定表單中的用戶輸入,可通俗的理解為:在單向綁定的基礎(chǔ)上給可輸入元素(input、textarea等)添加change(input)事件,來動(dòng)態(tài)修改model和view
vue當(dāng)中的雙向綁定
vue.js是采用數(shù)據(jù)劫持結(jié)合發(fā)布者-訂閱者模式的方式,通過Object.defineProperty()來劫持各個(gè)屬性的setter和getter,在數(shù)據(jù)變動(dòng)時(shí)發(fā)布消息給訂閱者,觸發(fā)相應(yīng)的監(jiān)聽回調(diào)
使用 v-model / .sync 實(shí)現(xiàn),v-model是 v-bind:value 和 v-on:input 的語法糖
v-bind
:value 實(shí)現(xiàn)了 data ⇒ UI 的單向綁定v-on
:input 實(shí)現(xiàn)了 UI ⇒ data 的單向綁定
引申出這兩個(gè)單向綁定如何實(shí)現(xiàn)
v-bind的實(shí)現(xiàn)
通過 Object.defineProperty API 給 data 創(chuàng)建 getter 和 setter,用于監(jiān)聽 data 的改變,data 一變就會(huì)安排改變 UI
v-on的實(shí)現(xiàn)
通過 template compiler 給 DOM 添加事件監(jiān)聽,DOM input 的值變了就會(huì)去修改 data。
Compile(指令解析器)
Compile主要做的事情是解析模板指令,將模板中變量替換成數(shù)據(jù),然后初始化渲染頁面視圖,并將每個(gè)指令對應(yīng)的節(jié)點(diǎn)綁定更新函數(shù),添加鑒定數(shù)據(jù)的訂閱者,一旦數(shù)據(jù)有變動(dòng),收到通知,更新視圖
Observer(數(shù)據(jù)監(jiān)聽器)
Observer的核心是通過Object.defineProprtty()來監(jiān)聽數(shù)據(jù)的變動(dòng),這個(gè)函數(shù)內(nèi)部可以定義setter和getter,每當(dāng)數(shù)據(jù)發(fā)生變化,就會(huì)觸發(fā)setter。這時(shí)候Observer就要通知訂閱者,訂閱者就是Watcher
Watcher(訂閱者)
Watcher訂閱者作為Observer和Compile之間通信的橋梁,主要做的事情是:
- 在自身實(shí)例化時(shí)往屬性訂閱器(dep)里面添加自己
- 自身必須有一個(gè)update()方法
- 待屬性變動(dòng)dep.notice()通知時(shí),能調(diào)用自身的update()方法,并觸發(fā)Compile中綁定的回調(diào)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
vue 項(xiàng)目打包時(shí)樣式及背景圖片路徑找不到的解決方式
今天小編就為大家分享一篇vue 項(xiàng)目打包時(shí)樣式及背景圖片路徑找不到的解決方式,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-11-11VUE引入騰訊地圖并實(shí)現(xiàn)軌跡動(dòng)畫的詳細(xì)步驟
這篇文章主要介紹了VUE引入騰訊地圖并實(shí)現(xiàn)軌跡動(dòng)畫,引入步驟大概是在 html 中通過引入 script 標(biāo)簽加載API服務(wù),結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下2022-09-09vue實(shí)現(xiàn)圖片下載點(diǎn)擊按鈕彈出本地窗口選擇自定義保存路徑功能
vue前端實(shí)現(xiàn)前端下載,并實(shí)現(xiàn)點(diǎn)擊按鈕彈出本地窗口,選擇自定義保存路徑,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧2023-12-12vue一步到位的實(shí)現(xiàn)動(dòng)態(tài)路由
這篇文章主要介紹了vue一步到位的實(shí)現(xiàn)動(dòng)態(tài)路由,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-06-06