国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

簡單實(shí)現(xiàn)一個(gè)雙向綁定

不知名網(wǎng)友 / 3218人閱讀

摘要:看了一些關(guān)于雙向綁定的文章,現(xiàn)在來整理一下思路。另一邊監(jiān)聽對應(yīng)視圖改變就直接監(jiān)聽事件。改變效果修改效果文章相關(guān)代碼已經(jīng)同步到,歡迎查閱

看了一些關(guān)于雙向綁定的文章,現(xiàn)在來整理一下思路。
首先實(shí)現(xiàn)雙向綁定有三個(gè)步驟:

需要一個(gè)方法來識別哪一個(gè)的view被綁定了相應(yīng)的數(shù)據(jù)

需要監(jiān)視數(shù)據(jù)和view的變化

需要將所有變化傳播到綁定的對象和對應(yīng)的view

為了解決第一個(gè)問題,要在對應(yīng)的dom上添加相應(yīng)的data-bind-屬性,比如:

  num: 
  

為了解決第二個(gè)問題,一方面監(jiān)聽數(shù)據(jù)改變,需要這樣添加一個(gè)set()方法進(jìn)行監(jiān)聽:

const Vue = {
  data: {
    num: 0
  },
  set(key, val) {
    this.data[key] = val
  }
}

規(guī)定通過set(key, val)的方式來修改數(shù)據(jù)。
另一邊監(jiān)聽對應(yīng)視圖改變就直接監(jiān)聽input事件。

為了解決第三個(gè)問題就需要用發(fā)布訂閱模式實(shí)現(xiàn)一個(gè)事件樞紐:

const EventHub = {
  callbacks: {},

  on(eventName, callback){
    this.callbacks[eventName] = this.callbacks[eventName] || [];
    this.callbacks[eventName].push(callback);
  },

  emit(eventName, ...rest){
    this.callbacks[eventName] = this.callbacks[eventName] || [];
    for(let i = 0; i < this.callbacks[eventName].length; i++){
      this.callbacks[eventName][i].call(this,...rest);
    }
  }
}

一方面將數(shù)據(jù)層的變化傳播到視圖,需要用特定名稱與dom上的屬性對應(yīng):

//觸發(fā)事件就修改視圖
eventHub.on("num:change", (val) => {
  $(`input[data-bind-num]`).val(val)
  $(`div[data-bind-num]`).text(val)
})
//通過set()修改data來觸發(fā)對應(yīng)的change事件
set(key, val) {
  this.data[key] = val
  EventHub.emit("num:change", val)
}

將視圖層的變化傳播到數(shù)據(jù):

$(`input[data-bind-num]`).on("input", function() {
  let val = $(this).val() === "" ? 0 : parseInt($(this).val())
  Vue.set(key, val)
})

至此雙向綁定就實(shí)現(xiàn)完成!但是這樣一個(gè)個(gè)寫事件名和屬性名有點(diǎn)蠢,優(yōu)化一下

const fn = (prop_name) => {     
  return {
    dataBind: `data-bind-${prop_name}`,//對應(yīng)dom的data屬性名
    eventName: `${prop_name}:change`//對應(yīng)數(shù)據(jù)的change事件名稱
  }      
}

//給所有data綁定change事件,給所有data對應(yīng)的view綁定input事件
Object.keys(Vue.data).map((key) => {
  //data修改改變view
  EventHub.on(fn(key).eventName, (val) => {

    $(`input[${fn(key).dataBind}]`).val(val)
    $(`div[${fn(key).dataBind}]`).text(val)

  })

  //view改變data
  $(`input[${fn(key).dataBind}]`).on("input", function() {

    let val = $(this).val() === "" ? "" : parseInt($(this).val())
    Vue.set(key, val)

  })
})

這樣實(shí)現(xiàn)的雙向綁定依賴于用set()來改變數(shù)據(jù),而我們都希望通過 vm.property = value 這種方式直接來修改數(shù)據(jù),這就需要用到Object.defineProperty()來劫持各個(gè)數(shù)據(jù)的getter,setter

//給各個(gè)數(shù)據(jù)添加監(jiān)聽器,用數(shù)據(jù)劫持替換原先的set(key,value)
const Observer = {
  mapProp(obj) {
    if(!obj || typeof obj !== "object") {
      return
    }
    Object.keys(obj).map((key) => {
      this.defineReactive(obj, key, obj[key])
    })
  },
  defineReactive(obj, key, val) {
    this.mapProp(val)
    Object.defineProperty(obj, key, {
      enumerable: true, // 可枚舉
      configurable: false, // 不能再define
      get() {
        return val
      },
      set(newVal) {
        console.log(`數(shù)據(jù) ${key} 從${val}->${newVal}`)
        //當(dāng)數(shù)據(jù)變化就貴觸發(fā)對應(yīng)的change事件
        EventHub.emit(fn(key).eventName, newVal)
        val = newVal
      }
    })
  }
}

這樣只需要調(diào)用一次Observer.mapProp(Vue.data)就會監(jiān)聽所有data,原先的set()都可以用直接賦值代替。

改變data效果:

修改input效果:

文章相關(guān)代碼已經(jīng)同步到Github,歡迎查閱~

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/95424.html

相關(guān)文章

  • 最近老是有兄弟問我,Vue雙向綁定的原理,以及簡單的原生js寫出來實(shí)現(xiàn),我就來一個(gè)簡單雙向綁定

    摘要:廢話不多說直接看效果圖代碼很好理解,但是在看代碼之前需要知道雙向綁定的原理其實(shí)就是基于實(shí)現(xiàn)的雙向綁定官方傳送門這里我們用官方的話來說方法會直接在一個(gè)對象上定義一個(gè)新屬性,或者修改一個(gè)對象的現(xiàn)有屬性,并返回這個(gè)對象。 廢話不多說直接看效果圖 showImg(https://segmentfault.com/img/bVbiYY5?w=282&h=500); 代碼很好理解,但是在看代碼之前...

    zhangfaliang 評論0 收藏0
  • 最近老是有兄弟問我,Vue雙向綁定的原理,以及簡單的原生js寫出來實(shí)現(xiàn),我就來一個(gè)簡單雙向綁定

    摘要:廢話不多說直接看效果圖代碼很好理解,但是在看代碼之前需要知道雙向綁定的原理其實(shí)就是基于實(shí)現(xiàn)的雙向綁定官方傳送門這里我們用官方的話來說方法會直接在一個(gè)對象上定義一個(gè)新屬性,或者修改一個(gè)對象的現(xiàn)有屬性,并返回這個(gè)對象。 廢話不多說直接看效果圖 showImg(https://segmentfault.com/img/bVbiYY5?w=282&h=500); 代碼很好理解,但是在看代碼之前...

    aristark 評論0 收藏0
  • JavaScript數(shù)據(jù)雙向綁定簡單演示

    摘要:對于前端,有時(shí)候需要實(shí)現(xiàn)視圖層和數(shù)據(jù)層的雙向綁定例如當(dāng)前流行的各種框架和類庫。為代表前端數(shù)據(jù)劫持。參考資料實(shí)現(xiàn)數(shù)據(jù)雙向綁定的三種方式談?wù)勚械碾p向數(shù)據(jù)綁定非常簡單的雙向數(shù)據(jù)綁定框架三 對于前端,有時(shí)候需要實(shí)現(xiàn)視圖層和數(shù)據(jù)層的雙向綁定(two-way-binding), 例如當(dāng)前流行的各種框架和類庫:Vue.js、Angular.js、React.js。 然而,他們最原始的實(shí)現(xiàn)方式其實(shí)都相...

    snifes 評論0 收藏0
  • 實(shí)現(xiàn)一個(gè)簡單雙向綁定

    摘要:下圖展示了實(shí)現(xiàn)雙向綁定的流程實(shí)現(xiàn)一個(gè)簡單的雙向綁定雙向綁定最最最初級進(jìn)階版操作是非常耗時(shí)和好性能,所以在優(yōu)化過程中先從操作入手。 接觸Vue有一段時(shí)間了,但是對于其雙向綁定的實(shí)現(xiàn)一直是似懂非懂,今天看到一篇寫的比較好的文章 傳送門1 根據(jù)原作者的指導(dǎo)自己也去實(shí)現(xiàn)了一遍簡單的 demo (本文的demo均基于Object.defineProperty 實(shí)現(xiàn)數(shù)據(jù)劫持,利用了對Vue.js實(shí)...

    elisa.yang 評論0 收藏0

發(fā)表評論

0條評論

最新活動(dòng)
閱讀需要支付1元查看
<