vue中v-model和響應(yīng)式的實(shí)現(xiàn)原理解析
v-model
- 首先要了解
v-model就是vue幫我們封裝的語法糖,真正實(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)
簡單一句話理解就是:通過重寫數(shù)據(jù)的get和set屬性方法,讓數(shù)據(jù)在被渲染時(shí)通過get屬性方法把所有用到自己的觀察者watcher放入自己的觀察者列表subs中,當(dāng)數(shù)據(jù)發(fā)生變化之后,通過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類:存放依賴的位置,通過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)建過程是先于子的,所以 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í)行都可以被跳過,所以父組件的 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í)無論如何都會(huì)進(jìn)行通知
這也就是為什么可以解釋watch數(shù)據(jù)的時(shí)候可以拿到新舊兩個(gè)值了watch: { num(new, old) {...} }


自己實(shí)現(xiàn)一個(gè)響應(yīng)式
根據(jù)以上分析,自己實(shí)現(xiàn)一個(gè)簡易版的數(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實(shí)現(xiàn)頁面加載動(dòng)畫效果
這篇文章主要為大家詳細(xì)介紹了vue實(shí)現(xiàn)頁面加載動(dòng)畫效果,vue頁面出現(xiàn)正在加載的初始頁面與實(shí)現(xiàn)動(dòng)畫效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-09-09
element-plus+Vue3實(shí)現(xiàn)表格數(shù)據(jù)動(dòng)態(tài)渲染
在Vue中,el-table是element-ui提供的強(qiáng)大表格組件,可以用于展示靜態(tài)和動(dòng)態(tài)表格數(shù)據(jù),本文主要介紹了element-plus+Vue3實(shí)現(xiàn)表格數(shù)據(jù)動(dòng)態(tài)渲染,感興趣的可以了解一下2024-03-03
vue復(fù)合組件實(shí)現(xiàn)注冊(cè)表單功能
這篇文章主要為大家詳細(xì)介紹了vue復(fù)合組件實(shí)現(xiàn)注冊(cè)表單功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-11-11
淺析Vue中Virtual?DOM和Diff原理及實(shí)現(xiàn)
這篇文章主要為大家詳細(xì)介紹了Vue中Virtual?DOM和Diff原理及實(shí)現(xiàn)的相關(guān)知識(shí),文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解一下2023-03-03
Vue實(shí)現(xiàn)監(jiān)聽某個(gè)元素滾動(dòng),親測(cè)有效
這篇文章主要介紹了Vue實(shí)現(xiàn)監(jiān)聽某個(gè)元素滾動(dòng),親測(cè)有效!具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-07-07
在vue中使用echarts實(shí)現(xiàn)飛機(jī)航線水滴圖詞云圖效果
這篇文章主要介紹了在vue中使用echarts實(shí)現(xiàn)飛機(jī)航線?水滴圖?詞云圖,通過引入中國地圖JS文件,會(huì)自動(dòng)注冊(cè)地圖,文中結(jié)合示例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下2022-08-08

