欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

用ES6的class模仿Vue寫一個(gè)雙向綁定的示例代碼

 更新時(shí)間:2018年04月20日 14:02:30   作者:AIBBSHINBAJI  
本篇文章主要介紹了用ES6的class模仿Vue寫一個(gè)雙向綁定的示例代碼,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧

本文介紹了用ES6的class模仿Vue寫一個(gè)雙向綁定的示例代碼,分享給大家,具體如下:

最終效果如下:

構(gòu)造器(constructor)

構(gòu)造一個(gè)TinyVue對象,包含基本的el,data,methods

class TinyVue{
 constructor({el, data, methods}){
  this.$data = data
  this.$el = document.querySelector(el)
  this.$methods = methods
  // 初始化
  this._compile()
  this._updater()
  this._watcher()
 }
}

編譯器(compile)

用于解析綁定到輸入框和下拉框的v-model和元素的點(diǎn)擊事件@click。

先創(chuàng)建一個(gè)函數(shù)用來載入事件:

// el為元素tagName,attr為元素屬性(v-model,@click)
_initEvents(el, attr, callBack) {
 this.$el.querySelectorAll(el).forEach(i => {
  if(i.hasAttribute(attr)) {
   let key = i.getAttribute(attr)
   callBack(i, key)
  }
 })
}

載入輸入框事件

this._initEvents('input, textarea', 'v-model', (i, key) => {
 i.addEventListener('input', () => {
  Object.assign(this.$data, {[key]: i.value})
 })
})

載入選擇框事件

this._initEvents('select', 'v-model', (i, key) => {
 i.addEventListener('change', () => Object.assign(this.$data, {[key]: i.options[i.options.selectedIndex].value}))
})

載入點(diǎn)擊事件

點(diǎn)擊事件對應(yīng)的是methods中的事件

this._initEvents('*', '@click', (i, key) => {
 i.addEventListener('click', () => this.$methods[key].bind(this.$data)())
})

視圖更新器(updater)

同理先創(chuàng)建公共函數(shù)來處理不同元素中的視圖,包括input、textarea的value,select的選擇值,div的innerHTML

_initView(el, attr, callBack) {
 this.$el.querySelectorAll(el, attr, callBack).forEach(i => {
  if(i.hasAttribute(attr)) {
   let key = i.getAttribute(attr),
    data = this.$data[key]
   callBack(i, key, data)
  }
 })
}

更新輸入框視圖

this._initView('input, textarea', 'v-model', (i, key, data) => {
 i.value = data
})

更新選擇框視圖

this._initView('select', 'v-model', (i, key, data) => {
 i.querySelectorAll('option').forEach(v => {
  if(v.value == data) v.setAttribute('selected', true)
  else v.removeAttribute('selected')
 })
})

更新innerHTML

這里實(shí)現(xiàn)方法有點(diǎn)low,僅想到正則替換{{text}}

let regExpInner = /\{{ *([\w_\-]+) *\}}/g
this.$el.querySelectorAll("*").forEach(i => {
 let replaceList = i.innerHTML.match(regExpInner) || (i.hasAttribute('vueID') && i.getAttribute('vueID').match(regExpInner))
 if(replaceList) {
  if(!i.hasAttribute('vueID')) {
   i.setAttribute('vueID', i.innerHTML)
  }
  i.innerHTML = i.getAttribute('vueID')
  replaceList.forEach(v => {
   let key = v.slice(2, v.length - 2)
   i.innerHTML = i.innerHTML.replace(v, this.$data[key])
  })
 }
})

監(jiān)聽器(watcher)

數(shù)據(jù)變化之后更新視圖

<div id="app">
 <input type="text" v-model="text1"><br>
 <input type="text" v-model="text2"><br>
 <textarea type="text" v-model="text3"></textarea><br>
 <button @click="add">加一</button>
 <h1>您輸入的是:{{text1}}+{{text2}}+{{text3}}</h1>
 <select v-model="select">
  <option value="volvo">Volvo</option>
  <option value="saab">Saab</option>
 </select>
 <select v-model="select">
  <option value="volvo">Volvo</option>
  <option value="saab">Saab</option>
 </select>
 <h1>您選擇了:{{select}}</h1>
</div>
<script src="./TinyVue.js"></script>
<script>
 let app = new TinyVue({
  el: '#app',
  data: {
   text1: 123,
   text2: 456,
   text3: '文本框',
   select: 'saab'
  },
  methods: {
   add() {
    this.text1 ++
    this.text2 ++
   }
  }
 })
</script>

TinyVue全部代碼

class TinyVue{
 constructor({el, data, methods}){
  this.$data = data
  this.$el = document.querySelector(el)
  this.$methods = methods
  this._compile()
  this._updater()
  this._watcher()
 }
 _watcher(data = this.$data) {
  let that = this
  Object.keys(data).forEach(i => {
   let value = data[i]
   Object.defineProperty(data, i, {
    enumerable: true,
    configurable: true,
    get: function () {
     return value;
    },
    set: function (newVal) {
     if (value !== newVal) {
      value = newVal;
      that._updater()
     }
    }
   })
  })
 }
 _initEvents(el, attr, callBack) {
  this.$el.querySelectorAll(el).forEach(i => {
   if(i.hasAttribute(attr)) {
    let key = i.getAttribute(attr)
    callBack(i, key)
   }
  })
 }
 _initView(el, attr, callBack) {
  this.$el.querySelectorAll(el, attr, callBack).forEach(i => {
   if(i.hasAttribute(attr)) {
    let key = i.getAttribute(attr),
     data = this.$data[key]
    callBack(i, key, data)
   }
  })
 }
 _updater() {
  this._initView('input, textarea', 'v-model', (i, key, data) => {
   i.value = data
  })
  this._initView('select', 'v-model', (i, key, data) => {
   i.querySelectorAll('option').forEach(v => {
    if(v.value == data) v.setAttribute('selected', true)
    else v.removeAttribute('selected')
   })
  })
  let regExpInner = /\{{ *([\w_\-]+) *\}}/g
  this.$el.querySelectorAll("*").forEach(i => {
   let replaceList = i.innerHTML.match(regExpInner) || (i.hasAttribute('vueID') && i.getAttribute('vueID').match(regExpInner))
   if(replaceList) {
    if(!i.hasAttribute('vueID')) {
     i.setAttribute('vueID', i.innerHTML)
    }
    i.innerHTML = i.getAttribute('vueID')
    replaceList.forEach(v => {
     let key = v.slice(2, v.length - 2)
     i.innerHTML = i.innerHTML.replace(v, this.$data[key])
    })
   }
  })
 }
 _compile() {
  this._initEvents('*', '@click', (i, key) => {
   i.addEventListener('click', () => this.$methods[key].bind(this.$data)())
  })
  this._initEvents('input, textarea', 'v-model', (i, key) => {
   i.addEventListener('input', () => {
    Object.assign(this.$data, {[key]: i.value})
   })
  })
  this._initEvents('select', 'v-model', (i, key) => {
   i.addEventListener('change', () => Object.assign(this.$data, {[key]: i.options[i.options.selectedIndex].value}))
  })
 }
}

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • js插件Jcrop自定義截取圖片功能

    js插件Jcrop自定義截取圖片功能

    這篇文章主要為大家詳細(xì)介紹了js插件Jcrop自定義截取圖片功能 ,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-10-10
  • JavaScript中使用正則匹配多條,且獲取每條中的分組數(shù)據(jù)

    JavaScript中使用正則匹配多條,且獲取每條中的分組數(shù)據(jù)

    該問題在使用Ajax遠(yuǎn)程獲取某網(wǎng)頁數(shù)據(jù)時(shí)經(jīng)常遇見 如果目標(biāo)頁面是XML,就好辦了,實(shí)用XMLDOM可以很輕松完成任務(wù)。
    2010-11-11
  • Canvas?drawImage方法實(shí)現(xiàn)圖片壓縮詳解

    Canvas?drawImage方法實(shí)現(xiàn)圖片壓縮詳解

    這篇文章主要為大家介紹了Canvas?drawImage方法實(shí)現(xiàn)圖片壓縮詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-11-11
  • JavaScript利用Date實(shí)現(xiàn)簡單的倒計(jì)時(shí)實(shí)例

    JavaScript利用Date實(shí)現(xiàn)簡單的倒計(jì)時(shí)實(shí)例

    在日常開發(fā)的時(shí)候經(jīng)常遇到關(guān)于倒計(jì)時(shí)的需求,下面這篇文章就給主要介紹了JavaScript利用Date實(shí)現(xiàn)倒計(jì)時(shí)效果的方法示例,文中主要實(shí)現(xiàn)了倒計(jì)時(shí)和倒計(jì)時(shí)結(jié)束搶購的按鈕才可以被點(diǎn)擊的效果,有需要的朋友可以參考借鑒。
    2017-01-01
  • ECMAScript中函數(shù)function類型

    ECMAScript中函數(shù)function類型

    這篇文章主要介紹了ECMAScript中函數(shù)function類型的相關(guān)資料,需要的朋友可以參考下
    2015-06-06
  • JavaScript函數(shù)的一些注意要點(diǎn)小結(jié)及js匿名函數(shù)

    JavaScript函數(shù)的一些注意要點(diǎn)小結(jié)及js匿名函數(shù)

    本文給大家總結(jié)了javascript函數(shù)的一些注意要點(diǎn)及js匿名函數(shù),主要知識點(diǎn)有:函數(shù)的基本語法、函數(shù)的參數(shù)、函數(shù)的重載相關(guān)知識,對本文感興趣的朋友一起學(xué)習(xí)吧
    2015-11-11
  • 整理關(guān)于Bootstrap表單的慕課筆記

    整理關(guān)于Bootstrap表單的慕課筆記

    這篇文章主要為大家整理了關(guān)于Bootstrap表單的慕課筆記,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-03-03
  • 深入淺析JS的數(shù)組遍歷方法(推薦)

    深入淺析JS的數(shù)組遍歷方法(推薦)

    這篇文章主要介紹了深入淺析JS的數(shù)組遍歷方法(推薦)的相關(guān)資料,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下
    2016-06-06
  • 如何將JS的變量值傳遞給ASP變量

    如何將JS的變量值傳遞給ASP變量

    asp作為主頁面,外接一個(gè)js的,我想知道一下能否在js里面調(diào)用asp的變量值,如果能這些值是怎么傳遞過去的呢?本文將提供解決方法,需要的朋友可以參考下
    2012-12-12
  • require.js中的define函數(shù)詳解

    require.js中的define函數(shù)詳解

    這篇文章主要給大家介紹了關(guān)于require.js中define函數(shù)的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家學(xué)習(xí)或者使用require.js中的define函數(shù)具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起看看吧。
    2017-07-07

最新評論