国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > JavaScript > 正文

vue用Object.defineProperty手寫一個(gè)簡(jiǎn)單的雙向綁定的示例

2019-11-19 13:31:31
字體:
供稿:網(wǎng)友

前言 上次寫了一個(gè)Object.defineProperty() 不詳解,文末說要寫用它來寫個(gè)雙向綁定。說話算話,說來就來

前文鏈接 Object.defineProperty() 不詳解

先看最后效果

model演示.gif

什么是雙向綁定?

1.當(dāng)一個(gè)對(duì)象(或變量)的屬性改變,那么調(diào)用這個(gè)屬性的地方顯示也應(yīng)該改變,模型到視圖(model => view)

2.當(dāng)調(diào)用屬性的這個(gè)地方改變了這個(gè)屬性(通常是一個(gè)表單元素),那么這個(gè)對(duì)象(或變量)的屬性也會(huì)改為最新的值 ,即視圖到模型(view => model)

我們?cè)趺粗缹?duì)象的屬性變了?

上文說到,Object.defineProperty 設(shè)置對(duì)象屬性的描述字段里面有兩個(gè)屬性 set (設(shè)置屬性時(shí)被調(diào)用)和get(獲取屬性時(shí)被調(diào)用),只說不練,你再講什么?眼見為實(shí)好嗎?OK ,上代碼

var user = {};var defaultName = "狂奔的蝸牛";Object.defineProperty(user,"name",{  get:function(){    console.log("你是不是來獲取值啦");    return defaultName;  },  set:function(value){    console.log("你是不是來設(shè)置值啦");    defaultName = value;  }})console.log(user.name);user.name = "狂奔的蘿卜";console.log(user.name);

get和set存取時(shí)被調(diào)用

如上圖所示 每當(dāng)我獲取user.name屬性時(shí),get方法被調(diào)用,get 方法對(duì)應(yīng)的函數(shù)被執(zhí)行,輸出 你是不是來獲取值啦;每當(dāng)我設(shè)置user.name屬性時(shí),set方法對(duì)應(yīng)的函數(shù)被執(zhí)行,輸出 你是不是來設(shè)置值啦 ; 是的,我們監(jiān)控到了代碼對(duì)user.name屬性的存取。

說明 假設(shè)id="model" 的元素的 value 是user.name的值,既然我們可以在改變屬性的執(zhí)行日志輸出(console.log("你是不是來設(shè)置值啦");),那么,我們?cè)谠O(shè)置值的時(shí)候給id="model" 的元素設(shè)置下新值,不就實(shí)現(xiàn)了從模型到視圖??。?,說干就干

模型到視圖(model => view)的同步

說明 假設(shè)id="model" 的元素的 value 是user.name的值,既然我們可以在改變屬性的執(zhí)行日志輸出(console.log("你是不是來設(shè)置值啦");),那么,我們?cè)谠O(shè)置值的時(shí)候給id="model" 的元素設(shè)置下新值,不就實(shí)現(xiàn)了從模型到視圖???!,說干就干

<body>  手寫一個(gè)簡(jiǎn)單雙向綁定<br/>  <input type="text" id="model"><br/>  <div id="modelText"></div></body><script>var user = {};var defaultName = "狂奔的蝸牛";document.querySelector("#model").value = defaultName;document.querySelector("#modelText").textContent = defaultName;//定義屬性 監(jiān)控改變Object.defineProperty(user,"name",{  get:function(){    console.log("你是不是來獲取值啦");    return defaultName;  },  set:function(newValue){    console.log("設(shè)置新值");    defaultName = newValue;    console.log("實(shí)現(xiàn) 模型 => 視圖");    document.querySelector("#model").value = newValue;    document.querySelector("#modelText").textContent = newValue;  }})console.log("2s 后改變值");setTimeout(() => {  //改變值  user.name = "狂奔的蘿卜";}, 2000);</script>

模型到視圖(model => view)的同步

視圖到模型(view => model)的同步

問: 我們能捕捉到view對(duì)值更改嗎?

答:可以??! id="model" 的input元素的 value 是user.name的值,填充在這個(gè)文本框里面,文本框有個(gè)“ keyup” 事件,當(dāng)我們?cè)谖谋究蛑休斎胛淖值臅r(shí)候,文本框的值會(huì)跟著改變,并且會(huì)連續(xù)觸發(fā)keyup事件,那么我們只需要監(jiān)聽這個(gè)事件,是不是就可以捕捉到view對(duì)值的更改了??既然文本框的值會(huì)跟著改變,我們獲取最新的值再把新值更新到user.name屬性,不就實(shí)現(xiàn)了視圖到模型(view => model)的同步?沒代碼說個(gè)啥

<body>  手寫一個(gè)簡(jiǎn)單雙向綁定<br/>  <input type="text" id="model"><br/>  <div id="modelText"></div></body><script>  var user = {};  var defaultName = "狂奔的蝸牛";  var model = document.querySelector("#model");  var modelText = document.querySelector("#modelText");  model.value = defaultName;  modelText.textContent = defaultName;  //定義屬性 監(jiān)控改變  Object.defineProperty(user,"name",{    get:function(){      console.log("你是不是來獲取值啦");      return defaultName;    },    set:function(newValue){      console.log("設(shè)置新值");      defaultName = newValue;      model.value = newValue;      modelText.textContent = newValue;    }  })  model.addEventListener("keyup", function () {    user.name = this.value;    console.log("實(shí)現(xiàn) 視圖 => 模型");  }, false)</script>

view2model.gif

【最終源碼】

在上述代碼的基礎(chǔ)上,加入了 用戶輸入中文的判斷(用戶輸入中文時(shí),頻繁觸發(fā) keyup事件,但實(shí)際上輸入并沒有結(jié)束。)

<!DOCTYPE html><html><head>  <meta charset="utf-8">  <title>雙向綁定</title></head><body>  手寫一個(gè)簡(jiǎn)單雙向綁定<br/>  <input type="text" id="model"><br/>  <div id="modelText"></div></body><script>  var model = document.querySelector("#model");  var modelText = document.querySelector("#modelText");  var defaultName = "defaultName";  var userInfo = {}  model.value = defaultName;  Object.defineProperty(userInfo, "name", {    get: function () {      return defaultName;    },    set: function (value) {      defaultName = value;      model.value = value;      console.log("-----value");      console.log(value);      modelText.textContent = value;    }  })  userInfo.name = "new value";  var isEnd = true;  model.addEventListener("keyup", function () {    if (isEnd) {      userInfo.name = this.value;    }  }, false)  //加入監(jiān)聽中文輸入事件  model.addEventListener("compositionstart", function () {    console.log("開始輸入中文");    isEnd = false;  })  model.addEventListener("compositionend", function () {    isEnd = true;    console.log("結(jié)束輸入中文");  })</script></html>

【完結(jié)】

Object.defineProperty 可以做很多好玩兒的,自己慢慢探索哈~

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持武林網(wǎng)。

發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 宁陵县| 江西省| 大余县| 京山县| 鲜城| 榕江县| 丰顺县| 江陵县| 扶绥县| 松溪县| 柳林县| 淮安市| 盘山县| 瓮安县| 泾源县| 苏尼特右旗| 德安县| 夹江县| 牡丹江市| 登封市| 安义县| 苏州市| 龙岩市| 门头沟区| 阜平县| 渝北区| 宜昌市| 太仆寺旗| 玛多县| 成都市| 鄂伦春自治旗| 桐庐县| 视频| 崇文区| 黄冈市| 张家界市| 隆子县| 罗平县| 武宣县| 阳城县| 东山县|