Rumah hujung hadapan web tutorial js 用ES6的class模仿Vue写一个双向绑定的例子

用ES6的class模仿Vue写一个双向绑定的例子

Jun 30, 2018 pm 05:21 PM
class es6 Pengikatan dua hala mengikat

本篇文章主要介绍了用ES6的class模仿Vue写一个双向绑定的示例代码,内容挺不错的,现在分享给大家,也给大家做个参考。

本文介绍了用ES6的class模仿Vue写一个双向绑定的示例代码,分享给大家,具体如下:

最终效果如下:

构造器(constructor)

构造一个TinyVue对象,包含基本的el,data,methods

1

2

3

4

5

6

7

8

9

10

11

class TinyVue{

 constructor({el, data, methods}){

  this.$data = data

  this.$el = document.querySelector(el)

  this.$methods = methods

  // 初始化

  this._compile()

  this._updater()

  this._watcher()

 }

}

Salin selepas log masuk

编译器(compile)

用于解析绑定到输入框和下拉框的v-model和元素的点击事件@click。

先创建一个函数用来载入事件:

1

2

3

4

5

6

7

8

9

// 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)

  }

 })

}

Salin selepas log masuk

载入输入框事件

1

2

3

4

5

this._initEvents('input, textarea', 'v-model', (i, key) => {

 i.addEventListener('input', () => {

  Object.assign(this.$data, {[key]: i.value})

 })

})

Salin selepas log masuk

载入选择框事件

1

2

3

this._initEvents('select', 'v-model', (i, key) => {

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

})

Salin selepas log masuk

载入点击事件

点击事件对应的是methods中的事件

1

2

3

this._initEvents('*', '@click', (i, key) => {

 i.addEventListener('click', () => this.$methods[key].bind(this.$data)())

})

Salin selepas log masuk

视图更新器(updater)

同理先创建公共函数来处理不同元素中的视图,包括input、textarea的value,select的选择值,p的innerHTML

1

2

3

4

5

6

7

8

9

_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)

  }

 })

}

Salin selepas log masuk

更新输入框视图

1

2

3

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

 i.value = data

})

Salin selepas log masuk

更新选择框视图

1

2

3

4

5

6

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')

 })

})

Salin selepas log masuk

更新innerHTML

这里实现方法有点low,仅想到正则替换{{text}}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

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])

  })

 }

})

Salin selepas log masuk

监听器(watcher)

数据变化之后更新视图

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

<p 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>

</p>

<script src="./TinyVue.js"></script>

<script>

 let app = new TinyVue({

  el: &#39;#app&#39;,

  data: {

   text1: 123,

   text2: 456,

   text3: &#39;文本框&#39;,

   select: &#39;saab&#39;

  },

  methods: {

   add() {

    this.text1 ++

    this.text2 ++

   }

  }

 })

</script>

Salin selepas log masuk

TinyVue全部代码

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

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(&#39;input, textarea&#39;, &#39;v-model&#39;, (i, key, data) => {

   i.value = data

  })

  this._initView(&#39;select&#39;, &#39;v-model&#39;, (i, key, data) => {

   i.querySelectorAll(&#39;option&#39;).forEach(v => {

    if(v.value == data) v.setAttribute(&#39;selected&#39;, true)

    else v.removeAttribute(&#39;selected&#39;)

   })

  })

  let regExpInner = /\{{ *([\w_\-]+) *\}}/g

  this.$el.querySelectorAll("*").forEach(i => {

   let replaceList = i.innerHTML.match(regExpInner) || (i.hasAttribute(&#39;vueID&#39;) && i.getAttribute(&#39;vueID&#39;).match(regExpInner))

   if(replaceList) {

    if(!i.hasAttribute(&#39;vueID&#39;)) {

     i.setAttribute(&#39;vueID&#39;, i.innerHTML)

    }

    i.innerHTML = i.getAttribute(&#39;vueID&#39;)

    replaceList.forEach(v => {

     let key = v.slice(2, v.length - 2)

     i.innerHTML = i.innerHTML.replace(v, this.$data[key])

    })

   }

  })

 }

 _compile() {

  this._initEvents(&#39;*&#39;, &#39;@click&#39;, (i, key) => {

   i.addEventListener(&#39;click&#39;, () => this.$methods[key].bind(this.$data)())

  })

  this._initEvents(&#39;input, textarea&#39;, &#39;v-model&#39;, (i, key) => {

   i.addEventListener(&#39;input&#39;, () => {

    Object.assign(this.$data, {[key]: i.value})

   })

  })

  this._initEvents(&#39;select&#39;, &#39;v-model&#39;, (i, key) => {

   i.addEventListener(&#39;change&#39;, () => Object.assign(this.$data, {[key]: i.options[i.options.selectedIndex].value}))

  })

 }

}

Salin selepas log masuk

以上就是本文的全部内容,希望对大家的学习有所帮助,更多相关内容请关注PHP中文网!

相关推荐:

Vue2.0 多 Tab切换组件的封装介绍

关于Vue表单demo v-model双向绑定的问题

Atas ialah kandungan terperinci 用ES6的class模仿Vue写一个双向绑定的例子. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn

Alat AI Hot

Undresser.AI Undress

Undresser.AI Undress

Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover

AI Clothes Remover

Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool

Undress AI Tool

Gambar buka pakaian secara percuma

Clothoff.io

Clothoff.io

Penyingkiran pakaian AI

AI Hentai Generator

AI Hentai Generator

Menjana ai hentai secara percuma.

Artikel Panas

R.E.P.O. Kristal tenaga dijelaskan dan apa yang mereka lakukan (kristal kuning)
2 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Tetapan grafik terbaik
2 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Cara Memperbaiki Audio Jika anda tidak dapat mendengar sesiapa
2 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌

Alat panas

Notepad++7.3.1

Notepad++7.3.1

Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina

SublimeText3 versi Cina

Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1

Hantar Studio 13.0.1

Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6

Dreamweaver CS6

Alat pembangunan web visual

SublimeText3 versi Mac

SublimeText3 versi Mac

Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Bolehkah dua akaun WeChat diikat pada kad bank yang sama? Bolehkah dua akaun WeChat diikat pada kad bank yang sama? Aug 25, 2023 pm 03:13 PM

Dua akaun WeChat tidak boleh terikat pada kad bank yang sama. Ikat kad bank ke akaun WeChat: 1. Buka aplikasi WeChat, klik pilihan "Saya", dan kemudian pilih pilihan "Bayar" 2. Pilih pilihan "Tambah Kad Bank" dan masukkan maklumat kad bank seperti yang digesa ; 3. Setelah kad bank berjaya diikat, pengguna boleh menggunakan kad bank untuk membuat pembayaran dan pemindahan dalam WeChat.

Bagaimana untuk melaksanakan jadual boleh diedit dalam Vue Bagaimana untuk melaksanakan jadual boleh diedit dalam Vue Nov 08, 2023 pm 12:51 PM

Jadual adalah komponen penting dalam banyak aplikasi web. Jadual biasanya mempunyai jumlah data yang besar, jadi jadual memerlukan beberapa ciri khusus untuk meningkatkan pengalaman pengguna. Salah satu ciri penting ialah keboleheditan. Dalam artikel ini, kami akan meneroka cara melaksanakan jadual boleh diedit menggunakan Vue.js dan memberikan contoh kod khusus. Langkah 1: Sediakan data Mula-mula, kita perlu menyediakan data untuk jadual. Kita boleh menggunakan objek JSON untuk menyimpan data jadual dan menyimpannya dalam sifat data bagi contoh Vue. Dalam kes ini

Cara menggunakan kelas dan kaedah dalam Python Cara menggunakan kelas dan kaedah dalam Python Apr 21, 2023 pm 02:28 PM

Konsep dan kejadian kelas dan kaedah Kelas (Kelas): digunakan untuk menerangkan koleksi objek dengan sifat dan kaedah yang sama. Ia mentakrifkan sifat dan kaedah yang biasa kepada setiap objek dalam koleksi. Objek ialah contoh kelas. Kaedah: Fungsi yang ditakrifkan dalam kelas. Kaedah pembinaan kelas __init__(): Kelas mempunyai kaedah khas (kaedah pembinaan) bernama init(), yang dipanggil secara automatik apabila kelas dijadikan instantiated. Pembolehubah instance: Dalam pengisytiharan kelas, atribut diwakili oleh pembolehubah tersebut dipanggil pembolehubah instance. Instantiation: Buat contoh kelas, objek khusus kelas. Warisan: iaitu, kelas terbitan (derivedclass) mewarisi kelas asas (baseclass)

Adakah async untuk es6 atau es7? Adakah async untuk es6 atau es7? Jan 29, 2023 pm 05:36 PM

async ialah es7. async dan await ialah penambahan baharu kepada ES7 dan merupakan penyelesaian untuk operasi asynchronous/wait boleh dikatakan sebagai gula sintaktik untuk modul bersama dan fungsi penjana, menyelesaikan kod tak segerak dengan semantik yang lebih jelas. Seperti namanya, async bermaksud "tak segerak".

Tutorial BTCC: Bagaimana untuk mengikat dan menggunakan dompet MetaMask pada pertukaran BTCC? Tutorial BTCC: Bagaimana untuk mengikat dan menggunakan dompet MetaMask pada pertukaran BTCC? Apr 26, 2024 am 09:40 AM

MetaMask (juga dipanggil Little Fox Wallet dalam bahasa Cina) ialah perisian dompet penyulitan percuma dan diterima baik. Pada masa ini, BTCC menyokong pengikatan pada dompet MetaMask Selepas mengikat, anda boleh menggunakan dompet MetaMask untuk log masuk dengan cepat, menyimpan nilai, membeli syiling, dsb., dan anda juga boleh mendapatkan bonus percubaan 20 USDT untuk pengikatan pertama. Dalam tutorial dompet BTCCMetaMask, kami akan memperkenalkan secara terperinci cara mendaftar dan menggunakan MetaMask, dan cara mengikat dan menggunakan dompet Little Fox dalam BTCC. Apakah dompet MetaMask? Dengan lebih 30 juta pengguna, MetaMask Little Fox Wallet ialah salah satu dompet mata wang kripto yang paling popular hari ini. Ia percuma untuk digunakan dan boleh dipasang pada rangkaian sebagai sambungan

Bagaimana untuk mengikat sub-akaun pada Xiaohongshu? Bagaimanakah ia menyemak sama ada akaun itu normal? Bagaimana untuk mengikat sub-akaun pada Xiaohongshu? Bagaimanakah ia menyemak sama ada akaun itu normal? Mar 21, 2024 pm 10:11 PM

Dalam era ledakan maklumat hari ini, pembinaan jenama peribadi dan imej korporat telah menjadi semakin penting. Sebagai platform perkongsian kehidupan fesyen terkemuka di China, Xiaohongshu telah menarik sejumlah besar perhatian dan penyertaan pengguna. Bagi pengguna yang ingin mengembangkan pengaruh mereka dan meningkatkan kecekapan penyebaran kandungan, sub-akaun yang mengikat telah menjadi cara yang berkesan. Jadi, bagaimanakah Xiaohongshu mengikat sub-akaun? Bagaimana untuk menyemak sama ada akaun itu normal? Artikel ini akan menjawab soalan-soalan ini untuk anda secara terperinci. 1. Bagaimana untuk mengikat sub-akaun pada Xiaohongshu? 1. Log masuk ke akaun utama anda: Pertama, anda perlu log masuk ke akaun utama Xiaohongshu anda. 2. Buka menu tetapan: klik "Saya" di penjuru kanan sebelah atas, dan kemudian pilih "Tetapan". 3. Masukkan pengurusan akaun: Dalam menu tetapan, cari pilihan "Pengurusan Akaun" atau "Pembantu Akaun" dan klik

Langkah dan kaedah untuk mengikat Douyin dalam Toutiao Langkah dan kaedah untuk mengikat Douyin dalam Toutiao Mar 22, 2024 pm 05:56 PM

1. Buka Toutiao. 2. Klik Saya di penjuru kanan sebelah bawah. 3. Klik [System Settings]. 4. Klik [Tetapan Akaun dan Privasi]. 5. Klik butang di sebelah kanan [Douyin] untuk mengikat Douyin.

Bagaimana untuk mengikat apl Cainiao ke Pinduoduo? Bagaimana untuk menambah Cainiao Wrap ke platform Pinduoduo? Bagaimana untuk mengikat apl Cainiao ke Pinduoduo? Bagaimana untuk menambah Cainiao Wrap ke platform Pinduoduo? Mar 19, 2024 pm 02:30 PM

Aplikasi Cainiao ialah platform yang boleh memberikan anda pelbagai maklumat logistik Fungsi di sini sangat berkuasa dan mudah digunakan Jika anda mempunyai sebarang masalah berkaitan logistik, ia boleh diselesaikan di sini -perkhidmatan berhenti boleh menyelesaikan segala-galanya dalam masa Menyemak penghantaran ekspres, mengambil penghantaran ekspres, dan lain-lain semuanya tanpa sebarang masalah. Kami telah bekerjasama dengan pelbagai platform dan semua maklumat boleh ditanya Mungkin berlaku bahawa barang yang dibeli di Pinduoduo tidak dapat memaparkan maklumat logistik Sebenarnya, anda perlu mengikat Pinduoduo secara manual untuk mencapai ini. Cara mengikat Cainiao ke akaun Pinduoduo: 1. Buka APP Cainiao dan pergi ke halaman utama

See all articles