vue中v-model和響應(yīng)式的實(shí)現(xiàn)原理解析
v-model
- 首先要了解
v-model就是vue幫我們封裝的語(yǔ)法糖,真正實(shí)現(xiàn)靠的還是:- v-bind:綁定響應(yīng)式數(shù)據(jù) 觸發(fā) input 事件 并傳遞數(shù)據(jù)
例如下面示例:
<template> // 這兩種寫法等價(jià) <input v-bind:name="name" v-on:input="name=$event.target.value"/> <input v-model="name"/> </template>
1、使用v-model經(jīng)典例子
textarea元素select下拉框input type='radio'單選框input type='checkbox'多選框
2、使用v-model的副作用
綁定的響應(yīng)式對(duì)象某個(gè)不存在的屬性,那么vue會(huì)悄悄增加這個(gè)屬性,并設(shè)置為響應(yīng)式
// template中:
<el-input v-model="user.tel"></el-input>
// script中:
export default {
data() {
return {
user: {
name: 'xxx',
}
}
}
}3、自己開發(fā)的組件如何支持v-model
model屬性的默認(rèn)值為
// 默認(rèn)的 model 屬性
export default {
model: {
prop: 'value',
event: 'input'
},
data() {...},
methods: {...},
}響應(yīng)式實(shí)現(xiàn)
簡(jiǎn)單一句話理解就是:通過(guò)重寫數(shù)據(jù)的get和set屬性方法,讓數(shù)據(jù)在被渲染時(shí)通過(guò)get屬性方法把所有用到自己的觀察者watcher放入自己的觀察者列表subs中,當(dāng)數(shù)據(jù)發(fā)生變化之后,通過(guò)set屬性方法將該變化通知給所有的觀察者watcher,達(dá)到重新渲染。
- 使用觀察者模式
- 底層使用
Object.defineProperty(),給所有的數(shù)據(jù)都添加getter和setter方法 - 主要涉及到三個(gè)函數(shù):
Dep:被觀察者類,每個(gè)data都有一個(gè)Dep實(shí)例對(duì)象,用于Observer的data觸發(fā)getter時(shí)執(zhí)行dep.depend收集依賴的watcherWatcher:觀察者類,依賴收集以后Watcher對(duì)象會(huì)被保存在Dep的subs中,數(shù)據(jù)變動(dòng)的時(shí)候Dep會(huì)通知Watcher實(shí)例,然后由Watcher實(shí)例回調(diào)cb進(jìn)行視圖的更新。Observer:將普通數(shù)據(jù)轉(zhuǎn)化為響應(yīng)式數(shù)據(jù)
實(shí)現(xiàn)響應(yīng)式的主要流程:
1、Observer類的構(gòu)造方法
- 給當(dāng)前的數(shù)據(jù)對(duì)象新建一個(gè)訂閱器Dep
- 遍歷對(duì)象的 key 調(diào)用 defineReactive 方法(實(shí)際綁定getter和setter的地方。get 方法是對(duì)依賴進(jìn)行收集, set 方法是當(dāng)數(shù)據(jù)改變時(shí)通知 Watcher 派發(fā)更新)
2、收集依賴
視圖被渲染時(shí),觸發(fā)get屬性方法,調(diào)用dep的一個(gè)方法dep.depend進(jìn)行依賴收集
- Watcher類:依賴就是watcher的實(shí)例
- Dep類:存放依賴的位置,通過(guò)Dep.subs[]進(jìn)行管理依賴
舉個(gè)??
當(dāng)前正在渲染componentA時(shí),組件用到了數(shù)據(jù) data () { return { a: b + 1} },那么此時(shí)就會(huì)觸發(fā)b的get屬性方法,將當(dāng)前的watcher添加到b的訂閱者列表subs中
3、派發(fā)更新
修改data屬性上的某一個(gè)值時(shí),會(huì)它的觸發(fā)set屬性方法,根據(jù)自身的dep.notify(subs保存著所有的觀察者,在 notify 方法中首先對(duì) subs 這個(gè)觀察者列表按照其 id 進(jìn)行了排序)開始派發(fā)更新
為什么要進(jìn)行排序?
- 組件的更新由父到子;因?yàn)楦附M件的創(chuàng)建過(guò)程是先于子的,所以 watcher 的創(chuàng)建也是先父后子,執(zhí)行順序也應(yīng)該保持先父后子。
- 用戶的自定義 watcher 要優(yōu)先于渲染 watcher 執(zhí)行;因?yàn)橛脩糇远x watcher 是在渲染 watcher 之前創(chuàng)建的。
- 如果一個(gè)組件在父組件的 watcher 執(zhí)行期間被銷毀,那么它對(duì)應(yīng)的 watcher 執(zhí)行都可以被跳過(guò),所以父組件的 watcher 應(yīng)該先執(zhí)行。
排序結(jié)束以后,會(huì)對(duì)這個(gè)隊(duì)列進(jìn)行遍歷,執(zhí)行watcher.run()方法實(shí)現(xiàn)數(shù)據(jù)更新通知
run的邏輯是:
- 新的值與老的值不同時(shí)會(huì)觸發(fā)通知;
- 但是當(dāng)值是對(duì)象或者 deep 為 true 時(shí)無(wú)論如何都會(huì)進(jìn)行通知
這也就是為什么可以解釋watch數(shù)據(jù)的時(shí)候可以拿到新舊兩個(gè)值了watch: { num(new, old) {...} }


自己實(shí)現(xiàn)一個(gè)響應(yīng)式
根據(jù)以上分析,自己實(shí)現(xiàn)一個(gè)簡(jiǎn)易版的數(shù)據(jù)雙向綁定
借鑒文章
到此這篇關(guān)于vue中v-model和響應(yīng)式的實(shí)現(xiàn)原理的文章就介紹到這了,更多相關(guān)vue v-model響應(yīng)式原理內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- vue3自定義組件之v-model實(shí)現(xiàn)父子組件雙向綁定
- vue自定義組件實(shí)現(xiàn)v-model雙向綁定數(shù)據(jù)的實(shí)例代碼
- 淺談vue實(shí)現(xiàn)雙向事件綁定v-model的原理
- vue使用v-model進(jìn)行跨組件綁定的基本實(shí)現(xiàn)方法
- vue.js使用v-model實(shí)現(xiàn)父子組件間的雙向通信示例
- vue.js自定義組件實(shí)現(xiàn)v-model雙向數(shù)據(jù)綁定的示例代碼
- vue3實(shí)現(xiàn)v-model原理詳解
- Vue v-model實(shí)現(xiàn)案例介紹
相關(guān)文章
Vue開發(fā)配置tsconfig.json文件的實(shí)現(xiàn)
tsconfig.json文件中指定了用來(lái)編譯這個(gè)項(xiàng)目的根文件和編譯選項(xiàng),本文就來(lái)介紹一下Vue開發(fā)配置tsconfig.json文件的實(shí)現(xiàn),感興趣的可以了解一下2023-08-08
基于vue實(shí)現(xiàn)swipe輪播組件實(shí)例代碼
本篇文章主要介紹了基于vue實(shí)現(xiàn)swipe輪播組件實(shí)例代碼,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-05-05
vue.js利用defineProperty實(shí)現(xiàn)數(shù)據(jù)的雙向綁定
本篇文章主要介紹了用Node.js當(dāng)作后臺(tái)、jQuery寫前臺(tái)AJAX代碼實(shí)現(xiàn)用戶登錄和注冊(cè)的功能的相關(guān)知識(shí)。具有很好的參考價(jià)值。下面跟著小編一起來(lái)看下吧2017-04-04
vue 返回上一頁(yè),頁(yè)面樣式錯(cuò)亂的解決
今天小編就為大家分享一篇vue 返回上一頁(yè),頁(yè)面樣式錯(cuò)亂的解決,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-11-11
Vue選項(xiàng)之propsData傳遞數(shù)據(jù)方式
這篇文章主要介紹了Vue選項(xiàng)之propsData傳遞數(shù)據(jù)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-10-10
vue限制輸入數(shù)字或者保留兩位小數(shù)實(shí)現(xiàn)
這篇文章主要為大家介紹了vue限制輸入數(shù)字或者保留兩位小數(shù)實(shí)現(xiàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-07-07
基于vue與element實(shí)現(xiàn)創(chuàng)建試卷相關(guān)功能(實(shí)例代碼)
這篇文章主要介紹了基于vue與element實(shí)現(xiàn)創(chuàng)建試卷相關(guān)功能,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-12-12

