浅谈Vue之双向绑定
VUE實(shí)現(xiàn)雙向數(shù)據(jù)綁定的原理就是利用了 Object.defineProperty() 這個方法重新定義了對象獲取屬性值(get)和設(shè)置屬性值(set)的操作來實(shí)現(xiàn)的。那么Object.defineProperty究竟是該如何使用的呢?先看個例子
?
<!DOCTYPE html> <html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>Document</title> </head><body><div id="app"><h5 id="txtShow"></h5><input type="text" id="txt"></div><script>// mvvm 分為model(模型) view(視圖) viewModel(視圖模型)// model 用來存儲數(shù)據(jù)// view 用來展示數(shù)據(jù)// ViewModel 關(guān)聯(lián)數(shù)據(jù),和model實(shí)現(xiàn)雙向綁定。// 通過Object.defineProperty 定義一個屬性// 通過此方法為對象設(shè)置屬性的時(shí)候 對象的屬性值會包含一個get和set方法// 當(dāng)修改對象值得時(shí)候回觸發(fā)相應(yīng)的函數(shù)調(diào)用// 參數(shù)一 需要定義屬性的對象// 參數(shù)二 屬性名字// 參數(shù)三 對象屬性的修飾內(nèi)容 // 在set方法中做一些處理,執(zhí)行頁面的刷新和回調(diào)var model = {}; //創(chuàng)建一個新對象var vm = '';Object.defineProperty(model, 'txt', {set: function (val) {console.log('設(shè)置屬性值');console.log(val);vm = val;txtShow.innerHTML = this.txt;},get: function () {console.log('獲取屬性值');console.log(this);return vm;},enumerable: true, //可枚舉,默認(rèn)falseconfigurable: true //該屬性描述符能夠被改變,同時(shí)該屬性也能從對應(yīng)的對象上被刪除。默認(rèn)false })var txtShow = document.getElementById('txtShow'),txt = document.getElementById('txt');txt.onkeyup = function () {if (event.keyCode == 13) {model.txt = txt.value;}}</script> </body></html>?
通過上面的代碼我們可以看到,在控制臺,無論是改變vm的值還是model.txt的值,所對應(yīng)的的,對方的值也會相應(yīng)的改變,由此,這里我們就實(shí)現(xiàn)了雙向綁定。
對于Object.defineProperty()?,大家應(yīng)該都見過,只是認(rèn)知的程度有所不同。
根據(jù)MDN web docs 中解釋說:?Object.defineProperty()?方法會直接在一個對象上定義一個新屬性,或者修改一個對象的現(xiàn)有屬性, 并返回這個對象。
語法
Object.defineProperty(obj, prop, descriptor) 參數(shù)
obj返回值
? ? 被傳遞給函數(shù)的對象。
該方法允許精確添加或修改對象的屬性。通過賦值操作添加的普通屬性是可枚舉的,能夠在屬性枚舉期間呈現(xiàn)出來(for...in?或?Object.keys?方法),?這些屬性的值可以被改變,也可以被刪除。這個方法允許修改默認(rèn)的額外選項(xiàng)(或配置)。默認(rèn)情況下,使用?Object.defineProperty()?添加的屬性值是不可修改的。
對象里目前存在的屬性描述符有兩種主要形式:數(shù)據(jù)描述符和存取描述符。數(shù)據(jù)描述符是一個具有值的屬性,該值可能是可寫的,也可能不是可寫的。存取描述符是由getter-setter函數(shù)對描述的屬性。描述符必須是這兩種形式之一;不能同時(shí)是兩者。
數(shù)據(jù)描述符和存取描述符均具有以下可選鍵值:
configurable數(shù)據(jù)描述符同時(shí)具有以下可選鍵值:
value存取描述符同時(shí)具有以下可選鍵值:
get| ? | ?configurable | ?enumerable | ?value | writable? | get? | ?set |
| 數(shù)據(jù)描述符 | ?YES | ?YES | ?YES | ?YES | ?NO | ?NO |
| 存取描述符 | ?YES | ?YES | ?NO | ?NO | ?YES | ?YES |
如果一個描述符不具有value,writable,get 和 set?任意一個關(guān)鍵字,那么它將被認(rèn)為是一個數(shù)據(jù)描述符。如果一個描述符同時(shí)有(value或writable)和(get或set)關(guān)鍵字,將會產(chǎn)生一個異常。
記住,這些選項(xiàng)不一定是自身屬性,如果是繼承來的也要考慮。為了確認(rèn)保留這些默認(rèn)值,你可能要在這之前凍結(jié)?Object.prototype,明確指定所有的選項(xiàng),或者通過?Object.create(null)將__proto__屬性指向null。
在日常運(yùn)用中,那你需要明白:
var o = {};o.a = 1; // 等同于 : Object.defineProperty(o, "a", {value : 1,writable : true,configurable : true,enumerable : true });// 另一方面, Object.defineProperty(o, "a", { value : 1 }); // 等同于 : Object.defineProperty(o, "a", {value : 1,writable : false,configurable : false,enumerable : false });
下面的例子展示了如何實(shí)現(xiàn)一個自存檔對象。 當(dāng)設(shè)置temperature?屬性時(shí),archive?數(shù)組會獲取日志條目。
function Archiver() {var temperature = null;var archive = [];Object.defineProperty(this, 'temperature', {get: function() {console.log('get!');return temperature;},set: function(value) {temperature = value;archive.push({ val: temperature });}});this.getArchive = function() { return archive; }; }var arc = new Archiver(); arc.temperature; // 'get!' arc.temperature = 11; arc.temperature = 13; arc.getArchive(); // [{ val: 11 }, { val: 13 }] 看到這個例子,你心中是不是有了些許想法?后面還有很多知識點(diǎn),有需要的可以去MDN進(jìn)行更加深入的了解,謝謝!
轉(zhuǎn)載于:https://www.cnblogs.com/gitByLegend/p/10553793.html
總結(jié)
以上是生活随笔為你收集整理的浅谈Vue之双向绑定的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: linux关闭ACPI电源管理模块
- 下一篇: html5倒计时秒杀怎么做,vue 设