溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

怎么在vue中利用Object.defineProperty實現(xiàn)雙向綁定

發(fā)布時間:2021-05-11 17:00:08 來源:億速云 閱讀:205 作者:Leah 欄目:web開發(fā)

這篇文章將為大家詳細講解有關怎么在vue中利用Object.defineProperty實現(xiàn)雙向綁定,文章內(nèi)容質(zhì)量較高,因此小編分享給大家做個參考,希望大家閱讀完這篇文章后對相關知識有一定的了解。

為什么要使用Vue

Vue是一款友好的、多用途且高性能的JavaScript框架,使用vue可以創(chuàng)建可維護性和可測試性更強的代碼庫,Vue允許可以將一個網(wǎng)頁分割成可復用的組件,每個組件都包含屬于自己的HTML、CSS、JavaScript,以用來渲染網(wǎng)頁中相應的地方,所以越來越多的前端開發(fā)者使用vue。

什么是雙向綁定?

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

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

我們怎么知道對象的屬性變了?

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

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

console.log(user.name);
user.name = "狂奔的蘿卜";
console.log(user.name);

怎么在vue中利用Object.defineProperty實現(xiàn)雙向綁定

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

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

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

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

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

<body>
  手寫一個簡單雙向綁定<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("設置新值");
    defaultName = newValue;
    console.log("實現(xiàn) 模型 => 視圖");
    document.querySelector("#model").value = newValue;
    document.querySelector("#modelText").textContent = newValue;
  }
})

console.log("2s 后改變值");

setTimeout(() => {
  //改變值
  user.name = "狂奔的蘿卜";
}, 2000);
</script>

怎么在vue中利用Object.defineProperty實現(xiàn)雙向綁定

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

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

問: 我們能捕捉到view對值更改嗎?

答:可以?。?id="model" 的input元素的 value 是user.name的值,填充在這個文本框里面,文本框有個“ keyup” 事件,當我們在文本框中輸入文字的時候,文本框的值會跟著改變,并且會連續(xù)觸發(fā)keyup事件,那么我們只需要監(jiān)聽這個事件,是不是就可以捕捉到view對值的更改了??既然文本框的值會跟著改變,我們獲取最新的值再把新值更新到user.name屬性,不就實現(xiàn)了視圖到模型(view => model)的同步?沒代碼說個啥

<body>
  手寫一個簡單雙向綁定<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("設置新值");
      defaultName = newValue;
      model.value = newValue;
      modelText.textContent = newValue;
    }
  })

  model.addEventListener("keyup", function () {
    user.name = this.value;
    console.log("實現(xiàn) 視圖 => 模型");
  }, false)
</script>

怎么在vue中利用Object.defineProperty實現(xiàn)雙向綁定

view2model.gif

【最終源碼】

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

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>雙向綁定</title>
</head>
<body>
  手寫一個簡單雙向綁定<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>

關于怎么在vue中利用Object.defineProperty實現(xiàn)雙向綁定就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內(nèi)容。

AI