1. 程式人生 > >JavaScript之實現一個簡單的Vue

JavaScript之實現一個簡單的Vue

方法 ole tro def pre 一個 進行 this upd

vue的使用相信大家都很熟練了,使用起來簡單。但是大部分人不知道其內部的原理是怎麽樣的,今天我們就來一起實現一個簡單的vue。

Object.defineProperty()

實現之前我們得先看一下Object.defineProperty的實現,因為vue主要是通過數據劫持來實現的,通過get、set來完成數據的讀取和更新。

var obj = {name:‘wclimb‘}
var age = 24
Object.defineProperty(obj,‘age‘,{
enumerable: true, // 可枚舉
configurable: false, // 不能再define
get () {
return age

},
set (newVal) {
console.log(‘我改變了‘,age +‘ -> ‘+newVal);
age = newVal
}
})

> obj.age
> 24

> obj.age = 25;
> 我改變了 24 -> 25
> 25
從上面可以看到通過get獲取數據,通過set監聽到數據變化執行相應操作,還是不明白的話可以去看看Object.defineProperty文檔。

流程圖

圖片描述(最多50字)

html代碼結構

<div id="wrap">
<p v-html="test"></p>

<input type="text" v-model="form">
<input type="text" v-model="form">
<button @click="changeValue">改變值</button>
{{form}}
</div>
js調用

JavaScript
new Vue({
el: ‘#wrap‘,
data:{
form: ‘這是form的值‘,
test: ‘<strong>我是粗體</strong>‘,

},
methods:{
changeValue(){
console.log(this.form)
this.form = ‘值被我改變了,氣不氣?‘
}
}
})
Vue結構

class Vue{
    constructor(){}
    proxyData(){}
    observer(){}
    compile(){}
    compileText(){}
}
class Watcher{
    constructor(){}
    update(){}
}

Vue constructor 構造函數主要是數據的初始化
proxyData 數據代理
observer 劫持監聽所有數據
compile 解析dom
compileText 解析dom裏處理純雙花括號的操作
Watcher 更新視圖操作
Vue constructor 初始化

class Vue{
    constructor(options = {}){
        this.$el = document.querySelector(options.el);
        let data = this.data = options.data; 
        // 代理data,使其能直接this.xxx的方式訪問data,正常的話需要this.data.xxx
        Object.keys(data).forEach((key)=&gt; {
            this.proxyData(key);
        });
        this.methods = obj.methods // 事件方法
        this.watcherTask = {}; // 需要監聽的任務列表
        this.observer(data); // 初始化劫持監聽所有數據
        this.compile(this.$el); // 解析dom
    }
}

上面主要是初始化操作,針對傳過來的數據進行處理

proxyData 代理data

class Vue{
constructor(options = {}){
......
}
proxyData(key){
let that = this;
Object.defineProperty(that, key, {
configurable: false,
enumerable: true,
get () {
return that.data[key];
},
set (newVal) {
that.data[key] = newVal;
}
});
}
}

上面主要是代理data到最上層,this.xxx的方式直接訪問data

observer 劫持監聽

class Vue{
constructor(options = {}){
......
}
proxyData(key){
......
}
observer(data){
let that = this
Object.keys(data).forEach(key=>{
let value = data[key]
this.watcherTask[key] = []
Object.defineProperty(data,key,{
configurable: false,
enumerable: true,
get(){
return value
},
set(newValue){
if(newValue !== value){
value = newValue
that.watcherTask[key].forEach(task => {
task.update()
})
}
}
})
})
}
}
同樣是使用Object.defineProperty來監聽數據,初始化需要訂閱的數據。

把需要訂閱的數據到push到watcherTask裏,等到時候需要更新的時候就可以批量更新數據了。

JavaScript之實現一個簡單的Vue