Heim >Web-Frontend >js-Tutorial >So verwenden Sie ES6-Klassen, um Vue zu imitieren und eine bidirektionale Bindung zu schreiben
Dieses Mal zeige ich Ihnen, wie Sie Vue zum Schreiben einer bidirektionalen Bindung nachahmen können. Das Folgende ist ein praktischer Fall.
Der endgültige Effekt ist wie folgt:Konstruktor (Konstruktor)
Konstruiert ein TinyVue-Objekt, einschließlich grundlegende Elemente, Daten, Methodenclass TinyVue{ constructor({el, data, methods}){ this.$data = data this.$el = document.querySelector(el) this.$methods = methods // 初始化 this._compile() this._updater() this._watcher() } }
Compiler (kompilieren)
wird zum Parsen von Klickereignissen des V-Modells und von Elementen verwendet, die an Eingabefelder und Dropdown-Felder gebunden sind @klick. Erstellen Sie zunächst eine Funktion zum Laden von Ereignissen:// 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) } }) }Eingabefeldereignis laden
this._initEvents('input, textarea', 'v-model', (i, key) => { i.addEventListener('input', () => { Object.assign(this.$data, {[key]: i.value}) }) })Auswahlfeldereignis laden
this._initEvents('select', 'v-model', (i, key) => { i.addEventListener('change', () => Object.assign(this.$data, {[key]: i.options[i.options.selectedIndex].value})) })Laden klicken Sie auf das Ereignis
Das Klickereignis entspricht dem Ereignis in den Methoden
this._initEvents('*', '@click', (i, key) => { i.addEventListener('click', () => this.$methods[key].bind(this.$data)()) })
View-Updater (Updater)
Erstellen Sie auf ähnliche Weise zunächst eine öffentliche Funktion, um verschiedene Ansichten im Element zu verarbeiten , einschließlich des Werts von input, textarea, des Auswahlwerts von select, innerHTML von p_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) } }) }Eingabefeldansicht aktualisieren
this._initView('input, textarea', 'v-model', (i, key, data) => { i.value = data })Auswahlfeldansicht aktualisieren
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 aktualisierenDie Implementierungsmethode hier ist etwas niedrig. Ich denke nur an den regulären Ersatz {{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]) }) } })
Watcher (Watcher)
Nachher aktualisiert Datenänderungen anzeigen<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: '#app', data: { text1: 123, text2: 456, text3: '文本框', select: 'saab' }, methods: { add() { this.text1 ++ this.text2 ++ } } }) </script>Alle Codes von 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})) }) } }Ich glaube, dass Sie die Methode beherrschen, nachdem Sie den Fall in diesem Artikel gelesen haben. Weitere spannende Informationen finden Sie in anderen verwandten Artikeln zum Thema PHP chinesische Website! Empfohlene Lektüre:
So verwenden Sie Vue, um eine Countdown-Schaltfläche zu implementieren
So verwenden Sie Vue, um bidirektionale Daten zu schreiben verbindlich
Das obige ist der detaillierte Inhalt vonSo verwenden Sie ES6-Klassen, um Vue zu imitieren und eine bidirektionale Bindung zu schreiben. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!