vue中v-model和響應式的實現(xiàn)原理解析
v-model
- 首先要了解
v-model
就是vue幫我們封裝的語法糖,真正實現(xiàn)靠的還是:- v-bind:綁定響應式數(shù)據(jù) 觸發(fā) input 事件 并傳遞數(shù)據(jù)
例如下面示例:
<template> // 這兩種寫法等價 <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
的副作用
綁定的響應式對象某個不存在的屬性,那么vue會悄悄增加這個屬性,并設置為響應式
// template中: <el-input v-model="user.tel"></el-input> // script中: export default { data() { return { user: { name: 'xxx', } } } }
3、自己開發(fā)的組件如何支持v-model
model屬性的默認值為
// 默認的 model 屬性 export default { model: { prop: 'value', event: 'input' }, data() {...}, methods: {...}, }
響應式實現(xiàn)
簡單一句話理解就是:通過重寫數(shù)據(jù)的get和set屬性方法,讓數(shù)據(jù)在被渲染時通過get屬性方法把所有用到自己的觀察者watcher放入自己的觀察者列表subs中,當數(shù)據(jù)發(fā)生變化之后,通過set屬性方法將該變化通知給所有的觀察者watcher,達到重新渲染。
- 使用觀察者模式
- 底層使用
Object.defineProperty()
,給所有的數(shù)據(jù)都添加getter
和setter
方法 - 主要涉及到三個函數(shù):
Dep
:被觀察者類,每個data都有一個Dep實例對象,用于Observer的data觸發(fā)getter時執(zhí)行dep.depend
收集依賴的watcherWatcher
:觀察者類,依賴收集以后Watcher對象會被保存在Dep的subs中,數(shù)據(jù)變動的時候Dep會通知Watcher實例,然后由Watcher實例回調cb進行視圖的更新。Observer
:將普通數(shù)據(jù)轉化為響應式數(shù)據(jù)
實現(xiàn)響應式的主要流程:
1、Observer
類的構造方法
- 給當前的數(shù)據(jù)對象新建一個訂閱器Dep
- 遍歷對象的 key 調用 defineReactive 方法(實際綁定getter和setter的地方。get 方法是對依賴進行收集, set 方法是當數(shù)據(jù)改變時通知 Watcher 派發(fā)更新)
2、收集依賴
視圖被渲染時,觸發(fā)get屬性方法,調用dep的一個方法dep.depend
進行依賴收集
- Watcher類:依賴就是watcher的實例
- Dep類:存放依賴的位置,通過Dep.subs[]進行管理依賴
舉個??
當前正在渲染componentA時,組件用到了數(shù)據(jù) data () { return { a: b + 1} }
,那么此時就會觸發(fā)b
的get屬性方法,將當前的watcher添加到b的訂閱者列表subs中
3、派發(fā)更新
修改data屬性上的某一個值時,會它的觸發(fā)set屬性方法,根據(jù)自身的dep.notify
(subs保存著所有的觀察者,在 notify 方法中首先對 subs 這個觀察者列表按照其 id 進行了排序)開始派發(fā)更新
為什么要進行排序?
- 組件的更新由父到子;因為父組件的創(chuàng)建過程是先于子的,所以 watcher 的創(chuàng)建也是先父后子,執(zhí)行順序也應該保持先父后子。
- 用戶的自定義 watcher 要優(yōu)先于渲染 watcher 執(zhí)行;因為用戶自定義 watcher 是在渲染 watcher 之前創(chuàng)建的。
- 如果一個組件在父組件的 watcher 執(zhí)行期間被銷毀,那么它對應的 watcher 執(zhí)行都可以被跳過,所以父組件的 watcher 應該先執(zhí)行。
排序結束以后,會對這個隊列進行遍歷,執(zhí)行watcher.run()方法實現(xiàn)數(shù)據(jù)更新通知
run的邏輯是:
- 新的值與老的值不同時會觸發(fā)通知;
- 但是當值是對象或者 deep 為 true 時無論如何都會進行通知
這也就是為什么可以解釋watch數(shù)據(jù)的時候可以拿到新舊兩個值了watch: { num(new, old) {...} }
自己實現(xiàn)一個響應式
根據(jù)以上分析,自己實現(xiàn)一個簡易版的數(shù)據(jù)雙向綁定
借鑒文章
到此這篇關于vue中v-model和響應式的實現(xiàn)原理的文章就介紹到這了,更多相關vue v-model響應式原理內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
Vue開發(fā)配置tsconfig.json文件的實現(xiàn)
tsconfig.json文件中指定了用來編譯這個項目的根文件和編譯選項,本文就來介紹一下Vue開發(fā)配置tsconfig.json文件的實現(xiàn),感興趣的可以了解一下2023-08-08vue.js利用defineProperty實現(xiàn)數(shù)據(jù)的雙向綁定
本篇文章主要介紹了用Node.js當作后臺、jQuery寫前臺AJAX代碼實現(xiàn)用戶登錄和注冊的功能的相關知識。具有很好的參考價值。下面跟著小編一起來看下吧2017-04-04Vue選項之propsData傳遞數(shù)據(jù)方式
這篇文章主要介紹了Vue選項之propsData傳遞數(shù)據(jù)方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-10-10vue限制輸入數(shù)字或者保留兩位小數(shù)實現(xiàn)
這篇文章主要為大家介紹了vue限制輸入數(shù)字或者保留兩位小數(shù)實現(xiàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-07-07基于vue與element實現(xiàn)創(chuàng)建試卷相關功能(實例代碼)
這篇文章主要介紹了基于vue與element實現(xiàn)創(chuàng)建試卷相關功能,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-12-12