面試題:你能寫一個Vue的雙向資料繫結嗎?
文章出處:呆頭呆腦丶---
在目前的前端面試中,vue的雙向資料繫結已經成為了一個非常容易考到的點,即使不能當場寫出來,至少也要能說出原理。本篇文章中我將會仿照vue寫一個雙向資料繫結的例項,名字就叫myVue吧。結合註釋,希望能讓大家有所收穫。
1、原理
Vue的雙向資料繫結的原理相信大家也都十分了解了,主要是透過Object物件的defineProperty屬性,重寫data的set和get函式來實現的
,這裡對原理不做過多描述,主要還是來實現一個例項。為了使程式碼更加的清晰,這裡只會實現最基本的內容,主要實現v-model,v-bind 和v-click三個命令,其他命令也可以自行補充。
新增網上的一張圖
2、實現
頁面結構很簡單,如下
包含:
1. 一個input,使用v-model指令 2. 一個button,使用v-click指令 3. 一個h3,使用v-bind指令。
我們最後會透過類似於vue的方式來使用我們的雙向資料繫結,結合我們的資料結構新增註釋
var app = new myVue({ el:'#app', data: { number: 0 }, methods: { increment: function() { this.number ++; }, } })
首先我們需要定義一個myVue建構函式:
function myVue(options) { }
為了初始化這個建構函式,給它新增一 個_init屬性
function myVue(options) { this._init(options); } myVue.prototype._init = function (options) { this.$options = options; // options 為上面使用時傳入的結構體,包括el,data,methods this.$el = document.querySelector(options.el); // el是 #app, this.$el是id為app的Element元素 this.$data = options.data; // this.$data = {number: 0} this.$methods = options.methods; // this.$methods = {increment: function(){}} }
接下來實現_obverse函式,對data進行處理,重寫data的set和get函式
並改造_init函式
myVue.prototype._obverse = function (obj) { // obj = {number: 0} var value; for (key in obj) { //遍歷obj物件 if (obj.hasOwnProperty(key)) { value = obj[key]; if (typeof value === 'object') { //如果值還是物件,則遍歷處理 this._obverse(value); } Object.defineProperty(this.$data, key, { //關鍵 enumerable: true, configurable: true, get: function () { console.log(`獲取${value}`); return value; }, set: function (newVal) { console.log(`更新${newVal}`); if (value !== newVal) { value = newVal; } } }) } } } myVue.prototype._init = function (options) { this.$options = options; this.$el = document.querySelector(options.el); this.$data = options.data; this.$methods = options.methods; this._obverse(this.$data); }
接下來我們寫一個指令類Watcher,用來繫結更新函式,實現對DOM元素的更新
function Watcher(name, el, vm, exp, attr) { this.name = name; //指令名稱,例如文字節點,該值設為"text" this.el = el; //指令對應的DOM元素 this.vm = vm; //指令所屬myVue例項 this.exp = exp; //指令對應的值,本例如"number" this.attr = attr; //繫結的屬性值,本例為"innerHTML" this.update(); } Watcher.prototype.update = function () { this.el[this.attr] = this.vm.$data[this.exp]; //比如 H3.innerHTML = this.data.number; 當number改變時,會觸發這個update函式,保證對應的DOM內容進行了更新。 }
更新_init函式以及_obverse函式
myVue.prototype._init = function (options) { //... this._binding = {}; //_binding儲存著model與view的對映關係,也就是我們前面定義的Watcher的例項。當model改變時,我們會觸發其中的指令類更新,保證view也能實時更新 //... } myVue.prototype._obverse = function (obj) { //... if (obj.hasOwnProperty(key)) { this._binding[key] = { // 按照前面的資料,_binding = {number: _directives: []} _directives: [] }; //... var binding = this._binding[key]; Object.defineProperty(this.$data, key, { //... set: function (newVal) { console.log(`更新${newVal}`); if (value !== newVal) { value = newVal; binding._directives.forEach(function (item) { // 當number改變時,觸發_binding[number]._directives 中的繫結的Watcher類的更新 item.update(); }) } } }) } } }
那麼如何將view與model進行繫結呢?接下來我們定義一個_compile函式,用來解析我們的指令(v-bind,v-model,v-clickde)等,並在這個過程中對view與model進行繫結。
myVue.prototype._init = function (options) { //... this._complie(this.$el); } myVue.prototype._complie = function (root) { root 為 id為app的Element元素,也就是我們的根元素 var _this = this; var nodes = root.children; for (var i = 0; i至此,我們已經實現了一個簡單vue的雙向繫結功能,包括v-bind, v-model, v-click三個指令。效果如下圖
附上全部程式碼,不到150行
html>myVue
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/2325/viewspace-2800168/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 面試題:你能寫一個 Vue 的雙向資料繫結嗎面試題Vue
- Vue資料雙向繫結原理Vue
- vue雙向資料繫結原理Vue
- 通俗易懂講解並手寫一個vue資料雙向繫結案例Vue
- 淺析vue的雙向資料繫結Vue
- vue中的雙向資料繫結原理Vue
- Vue 雙向資料繫結原理分析Vue
- vue.js雙向資料繫結Vue.js
- js 實現vue的雙向資料繫結JSVue
- vue資料雙向繫結的實現原理Vue
- 原始碼分析:Vue的雙向資料繫結原始碼Vue
- Vue props 雙向資料繫結方法Vue
- Vue 中雙向繫結 Vs 單向資料流Vue
- vue 雙向繫結(v-model 雙向繫結、.sync 雙向繫結、.sync 傳物件)Vue物件
- 基於vue實現的雙向資料繫結Vue
- 揭密 Vue 的雙向繫結Vue
- 西安電話面試:談談Vue資料雙向繫結原理,看看你的回答能打幾分面試Vue
- Vue雙向繫結初探Vue
- vue雙向繫結原理Vue
- Vue雙向繫結原理,教你一步一步實現雙向繫結Vue
- JS雙向資料繫結JS
- vue父子關係元件間的雙向資料繫結Vue元件
- vue雙向繫結盲區Vue
- Vue雙向繫結實現Vue
- Vue、MVVM、MVC、雙向繫結VueMVVMMVC
- vue2元件之間雙向資料繫結問題Vue元件
- 手動實現vue元件間的雙向資料繫結Vue元件
- vue雙向繫結的原理及實現雙向繫結MVVM原始碼分析VueMVVM原始碼
- 原生js雙向資料繫結JS
- [JS] 資料雙向繫結原理JS
- 從單向到雙向資料繫結
- 0 到 1 掌握:Vue 核心之資料雙向繫結Vue
- 手動簡單實現Vue雙向資料繫結Vue
- 為什麼你的 Angular 雙向資料繫結會失效?Angular
- vue生命週期、雙向繫結Vue
- vue實現prop雙向繫結Vue
- vue實踐:元件雙向繫結Vue元件
- vue v-model 雙向繫結Vue