久久久久在线观看_又色又爽又黄的免费视频播放_一区中文字幕_日韩电影在线播放

今日焦點 焦點資訊 營銷之道 企業報道 淘寶運營 網站建設 軟件開發 400電話
  當前位置: 首頁 » 資訊 » 軟件開發 » 正文

Vue.js響應式原理詳解

放大字體  縮小字體 發布日期:2018-02-10  來源:企業800網  作者:新格網  瀏覽次數:954  【去百度看看】
核心提示:本人是Java背景,許多年前剛接觸JavaScript時有點怪怪的,因為它沒有 getters 和 setters。隨著時間的推移,我開始喜歡上這個缺失的特性,因為相比Java大量的 getter 和 setter,它讓代碼更簡潔。例如,我們看看下面的Java代碼:

class Person{
String firstName;
String lastName; // 這個Demo中省略了一些構造器代碼 :) public void setFirstName(firstName) { this.firstName = firstName;
} public String getFirstName() { return firstName;
} public void setLastName(lastName) { this.lastName = lastName;
} public String getLastName() { return lastName;
}
}// Create instancePerson bradPitt = new Person();
bradPitt.setFirstName("Brad");
bradPitt.setLastName("Pitt");

Javascript開發人員永遠不會這樣做,相反他們會這樣:

var Person = function () {};var bradPitt = new Person();
bradPitt.firstName = 'Brad';
bradPitt.lastName = 'Pitt';

這要簡潔的多。通常簡潔更好,不是嗎?

的確如此,但有時我想獲取一些可以被修改的屬性,但我不用知道這些屬性是什么。例如,我們在Java代碼中擴展一個新的方法 getFullName()

class Person{    private String firstName;    private String lastName;    // 這個Demo中省略了一些構造器代碼 :)    public void setFirstName(firstName) {        this.firstName = firstName;
} public String getFirstName() { return firstName;
} public void setLastName(lastName) { this.lastName = lastName;
} public String getLastName() { return lastName;
} public String getFullName() { return firstName + " " + lastName;
}
}

Person bradPitt = new Person();
bradPitt.setFirstName("Brad");
bradPitt.setLastName("Pitt");// Prints 'Brad Pitt'System.out.println(bradPitt.getFullName());

在上面例子中, fullName 是一個計算過的屬性,它不是私有屬性,但總能返回正確的結果。

C# 和隱式的 getter/setters

我們來看看 C# 特性之一:隱式的 getters/setters,我真的很喜歡它。在 C# 中,如果需要,你可以定義 getters/setters,但是并不用這樣做,但是如果你決定要這么做,調用者就不必調用函數。調用者只需要直接訪問屬性,getter/setter 會自動在鉤子函數中運行:

public class Foo {    public string FirstName {get; set;}    public string LastName {get; set;}    public string FullName {get { return firstName + " " + lastName }; private set;}
}

我覺得這很酷...

現在,如果我想在Javascript中實現類似的功能,我會浪費很多時間,比如:

var person0 = {
firstName: 'Bruce',
lastName: 'Willis',
fullName: 'Bruce Willis',
setFirstName: function (firstName) { this.firstName = firstName; this.fullName = `${this.firstName} ${this.lastName}`;
},
setLastname: function (lastName) { this.lastName = lastName; this.fullName = `${this.firstName} ${this.lastName}`;
},
};
console.log(person0.fullName);
person0.setFirstName('Peter');
console.log(person0.fullName);

它會打印出:

"Bruce Willis"
"Peter Willis"

但使用 setXXX(value) 的方式并不夠'Javascripty'(是個玩笑啦)。

下面的方式可以解決這個問題:

var person1 = {
firstName: 'Brad',
lastName: 'Pitt',
getFullName: function () { return `${this.firstName} ${this.lastName}`;
},
};
console.log(person1.getFullName()); // 打印 "Brad Pitt"

現在我們回到被計算過的 getter。你可以設置 firstlast name,并簡單的合并它們的值:

person1.firstName = 'Peter'person1.getFullName(); // 返回 "Peter Pitt"

這的確更方便,但我還是不喜歡它,因為我們要定義一個叫getxxx()的方法,這也不夠'Javascripty'。許多年來,我一直在思考如何更好的使用 Javascript。

然后 Vue 出現了

在我的Youtube頻道,很多和Vue教程有關的視頻都講到,我習慣響應式開發,在更早的Angular1時代,我們叫它:數據綁定(Data Binding)。它看起來很簡單。你只需要在Vue實例的 data() 塊中定義一些數據,并綁定到HTML:

var vm = new Vue({
data() {
return {
greeting: 'Hello world!',
};
}
})<p>{greeting}</p>

顯然它會在用戶界面打印出 “Hello world!”

現在,如果你改變greeting的值,Vue引擎會對此作出反應并相應地更新視圖。

methods: {
onSomethingClicked() { this.greeting = "What's up";
},
}

很長一段時間我都在想,它是如何工作的?當某個對象的屬性發生變化時會觸發某個事件?或者Vue不停的調用 setInterval 去檢查是否更新?

通過閱讀Vue官方文檔,我才知道,改變一個對象屬性將隱式調用getter/setter,再次通知觀察者,然后觸發重新渲染,如下圖,這個例子來自官方的Vue.js文檔:

vue-r-1.png

但我還想知道:

  • 怎么讓數據自帶getter/setters

  • 這些隱式調用內部是怎樣的?

第一個問題很簡單:Vue為我們準備好了一切。當你添加新數據,Vue將會通過其屬性為其添加 getter/setters。但是我讓 foo.bar = 3? 會發生什么?

這個問題的答案出現在我和SVG & Vue專家Sarah Drasner的Twitter對話中:

vue-r-2.png

Timo: foo.bar=value;是怎么做到實時響應的?

Sarah: 這個問題很難在Twitter說清楚,可以看這篇文章

Timo: 但這篇文章并沒有解釋上面提到的問題。

Timo: 它們就像:分配一個值->調用setter->通知觀察者,不理解為什么在不使用setIntervalEvent的情況下,setter/getter就存在了。

Sarah: 我的理解是:你獲取的所有數據都在Vue實例data{}中被代理了。

顯然,她也是參考的官方文檔,之前我也讀過,所以我開始閱讀Vue源碼,以便更好的理解發生了什么。過了一會我想起在官方文檔看到一個叫 Object.defineProperty() 的方法,我找到它,如下:

export function defineReactive (
obj: Object,
key: string,
val: any,
customSetter?: ?Function,
shallow?: boolean
) { const dep = new Dep() const property = Object.getOwnPropertyDescriptor(obj, key) if (property && property.configurable === false) { return
} // 預定義getter/setters const getter = property && property.get const setter = property && property.set let childOb = !shallow && observe(val)
Object.defineProperty(obj, key, {
enumerable: true,
configurable: true, get: function reactiveGetter () { const value = getter ? getter.call(obj) : val if (Dep.target) {
dep.depend() if (childOb) {
childOb.dep.depend()
} if (Array.isArray(value)) {
dependArray(value)
}
} return value
}, set: function reactiveSetter (newVal) { const value = getter ? getter.call(obj) : val if (newVal === value || (newVal !== newVal && value !== value)) { return
} if (process.env.NODE_ENV !== 'production' && customSetter) {
customSetter()
} if (setter) {
setter.call(obj, newVal)
} else {
val = newVal
}
childOb = !shallow && observe(newVal)
dep.notify()
}
})
}

所以答案一直存在于文檔中:

把一個普通 Javascript 對象傳給 Vue 實例的 data 選項,Vue 將遍歷此對象所有的屬性,并使用 Object.defineProperty 把這些屬性全部轉為 getter/setterObject.defineProperty 是僅 ES5 支持,且無法 shim 的特性,這也就是為什么 Vue 不支持 IE8 以及更低版本瀏覽器的原因。

我只想簡單的了解 Object.defineProperty() 做了什么,所以我用一個例子簡單的給你講解一下:

var person2 = {
firstName: 'George',
lastName: 'Clooney',
};
Object.defineProperty(person2, 'fullName', {
get: function () { return `${this.firstName} ${this.lastName}`;
},
});
console.log(person2.fullName); // 打印 "George Clooney"

還記得文章開頭C#的隱式 getter 嗎?它們看起來很類似,但ES5才開始支持。你需要做的是使用 Object.defineProperty() 定義現有對象,以及何時獲取這個屬性,這個getter被稱為響應式——這實際上就是Vue在你添加新數據時背后所做的事。

Object.defineProperty()能讓Vue變的更簡化嗎?

學完這一切,我一直在想,Object.defineProperty() 是否能讓Vue變的更簡化?現今越來越多的新術語,是不是真的有必要把事情變得過于復雜,變的讓初學者難以理解(Redux也是同樣):

  • Mutator:或許你在說(隱式)setter

  • Getters:為什么不用 Object.defineProperty() 替換成(隱式)getter

  • store.commit():為什么不簡化成 foo = bar,而是 store.commit("setFoo", bar);

你是怎么認為的?Vuex必須是復雜的還是可以像 Object.defineProperty() 一樣簡單?

相關推薦:

javascript用rem來做響應式開發實例分享

詳解前端響應式布局、響應式圖片,與自制柵格系統

響應式和自適應有什么區別

以上就是Vue.js響應式原理詳解的詳細內容,更多請關注php中文網其它相關文章!

 
 
[ 資訊搜索 ]  [ 加入收藏 ]  [ 告訴好友 ]  [ 打印本文 ]  [ 違規舉報 ]  [ 關閉窗口 ]

 
0條 [查看全部]  相關評論

 
網站首頁 | 關于我們 | 聯系方式 | 使用協議 | 版權隱私 | 網站地圖 | 排名推廣 | 廣告服務 | 積分換禮 | 網站留言 | RSS訂閱 | 皖ICP備2021004516號-14
企業800網 · 提供技術支持