最近幾年前端技術(shù)棧真是發(fā)展的太迅速了,從以前的針對(duì)dom操作的框架如jquery,ext.js等框架逐步過(guò)渡到當(dāng)前的mvvm模式,讓前端開(kāi)發(fā)者將注意力從dom操作逐漸解脫出來(lái),專(zhuān)注于邏輯的實(shí)現(xiàn),個(gè)人認(rèn)為開(kāi)發(fā)效率至少提升了1倍,mvvm模式的一個(gè)核心便是數(shù)據(jù)的雙向綁定。
什么是數(shù)據(jù)的雙向綁定?
//vue 中實(shí)習(xí)數(shù)據(jù)雙向綁定的核心就在于v-model 如下
<input type="text" name="" v-model="userName">
當(dāng)輸入框中的內(nèi)容發(fā)生變化時(shí),如用戶(hù)在視圖view輸入hello world 此時(shí)我們?cè)趍odel層即用js處理邏輯代碼的地方就會(huì)獲取用戶(hù)輸入的值,反之在model層給與userName一個(gè)值時(shí),view層的值也會(huì)進(jìn)行同步,簡(jiǎn)而言之雙向指的是view層和model層 ,數(shù)據(jù)綁定即model上的數(shù)據(jù),在view和model是同步綁定關(guān)系的
上面說(shuō)的是在vue框架中數(shù)據(jù)雙向綁定的應(yīng)用,個(gè)人認(rèn)為這個(gè)特性很贊,是大幅提升開(kāi)發(fā)效率的關(guān)鍵,那如果脫離mvvm的框架,我也想實(shí)現(xiàn)這種數(shù)據(jù)的雙向綁定,可不可以實(shí)現(xiàn)了,該如何實(shí)現(xiàn)了?
用原生js模擬數(shù)據(jù)雙向綁定
實(shí)現(xiàn)步驟:
一:用js監(jiān)聽(tīng)數(shù)據(jù)的變化并將變化的數(shù)據(jù)時(shí)時(shí)的同步到頁(yè)面
為了實(shí)現(xiàn)這個(gè)功能我們需要用到j(luò)s的一個(gè)方法Object.defineProperty
1.屬性介紹
語(yǔ)法:Object.defineProperty(obj,prop,descriptor);
描述:obj:必需。目標(biāo)對(duì)象
prop:必需。需定義或修改的屬性的名字
descriptor:必需。目標(biāo)屬性所擁有的特性
用法:
var demo = {name:'json'};
Object.defineProperty(demo,'name',{
value:'jack'
})
//更改demo的name屬性值
demo.name = 'mike'
demo.name //輸出 jack
//有木有感覺(jué)很神奇,我們?cè)诳聪旅嬉粋€(gè)例子,對(duì)上面進(jìn)行稍微修改
var demo = {name:'json'};
Object.defineProperty(demo,'name',{
value:'jack',
writable:'true'
})
//更改demo的name屬性值
demo.name = 'mike';
//查看name屬性
demo.name // 輸出mike
//分析:上面涉及到了兩個(gè)屬性:value 和 writable 其中value是對(duì)name屬性進(jìn)行賦值,此時(shí)如果writable:‘false’,意思是不能對(duì)value值進(jìn)行重寫(xiě),默認(rèn)就是false,所以第一個(gè)例子中對(duì)name值進(jìn)行更改后并沒(méi)有生效,當(dāng)writable:'true'時(shí)就可以對(duì)value的值進(jìn)行重寫(xiě),如第二個(gè)例子中設(shè)置生效。
//小結(jié):value: 設(shè)置屬性的值
writable: 值是否可以重寫(xiě)。true | false
如果var demo = {}; 則上述方法就會(huì)為該對(duì)象添加一個(gè)name屬性并給其賦值
2.方法介紹
//先看實(shí)列
var demo = {name:'json'};
Object.defineProperty(demo,'name',{
set:function(value){
console.log('執(zhí)行了');
name = value;
},
get:function(){
return name;
}
})
demo.name = 'json';//修改name屬性值
//結(jié)果控制臺(tái)輸出:執(zhí)行了
demo.name //json
//小結(jié):當(dāng)修改defineProperty監(jiān)聽(tīng)的屬性是,會(huì)執(zhí)行該函數(shù)內(nèi)部的set方法 => 這樣是不是可以用作監(jiān)聽(tīng)器了像angular和vue中的$watch,當(dāng)目標(biāo)對(duì)象中的某個(gè)屬性發(fā)生變化時(shí)進(jìn)行相應(yīng)函數(shù)的調(diào)用,如在set函數(shù)中加一個(gè)自己的處理函數(shù)。
var demo = {name:'json'};
Object.defineProperty(demo,'name',{
set:function(value){
name = value;
},
get:function(){
console.log('獲取值了')
return name;
}
})
demo.name//控制臺(tái)輸出:獲取值了
var demo = {name:'json'};
Object.defineProperty(demo,'name',{
set:function(value){
console.log('我有執(zhí)行到嗎');
name = value;
},
get:function(){
return '看我變成啥樣了';
}
})
demo.name //"看我變成啥樣了"
//小結(jié)
當(dāng)查看defineProperty所監(jiān)聽(tīng)的屬性時(shí)如demo.name,此時(shí)會(huì)調(diào)用該函數(shù)內(nèi)部的get方法 獲取到的值即為return的值,如上代碼,而且當(dāng)只獲取屬性時(shí)不會(huì)進(jìn)入到set方法,反正亦然
大概的介紹了defineProperty核心的兩個(gè)方法,看到這里,你就知道可以利用這兩個(gè)內(nèi)置方法搞事情了,看下面利用該方法實(shí)現(xiàn)數(shù)據(jù)雙向綁定的一個(gè)例子
mvvm.png
效果如下,當(dāng)姓名發(fā)生變化時(shí)后面的輸入框中的值也同步發(fā)生變化:

model.png
小結(jié):雖然對(duì)此屬性沒(méi)有太研究,但是感覺(jué)還是蠻新鮮的,之前只是用到了mvvm模式帶來(lái)的便捷卻不知道如何去實(shí)現(xiàn),完全么有思路的說(shuō),但是小伙伴們,你們看完上述代碼,現(xiàn)在心中的疑惑應(yīng)該會(huì)少很多哈,,嘎嘎。