How to write a two-way binding using ES6's class
Today, I would like to share with you how to use ES6's class to write a two-way binding related knowledge, detailed content, clear logic, I believe that most people still know too much about this knowledge, so share this article for your reference, I hope you can learn something after reading this article, let's take a look at it.
The final effect is as follows:
Constructor (constructor)
Construct a TinyVue object that contains the basic el,data,methods
Class TinyVue {constructor ({el, data, methods}) {this.$data = data this.$el = document.querySelector (el) this.$methods = methods / / initialize this._compile () this._updater () this._watcher ()}}
Compiler (compile)
Used to parse the click event @ click of the v-model and element bound to the input box and drop-down box.
First create a function to load the event:
/ / el is the element tagName,attr is the element attribute (el, attr, callBack) {this.$el.querySelectorAll (el) .forEach (I = > {if (i.hasAttribute (attr)) {let key = i.getAttribute (attr) callBack (I, key)})}
Load input box event
This._initEvents ('input, textarea',' v key modelling, (I, key) = > {i.addEventListener ('input', () = > {Object.assign (this.$data, {[key]: i.value})}))
Load selection box event
This._initEvents ('select',' v key modelling, (I, key) = > {i.addEventListener ('change', () = > Object.assign (this.$data, {[key]: i.options.selectedIndex] .value})
Load click event
Click events correspond to events in methods
This._initEvents ('*','@ click', (I, key) = > {i.addEventListener ('click', () = > this.$ methods [key] .bind (this.$data) ()}))
View updater (updater)
Similarly, create a public function to deal with views in different elements, including the selection value of value,select for input and textarea, and innerHTML for div.
_ 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)}})}
Update input box view
This._initView ('input, textarea',' v key modelling, (I, key, data) = > {i.value = data})
Update selection box view
This._initView ('select',' v selected', true modelling, (I, key, data) = > {i.querySelectorAll ('option') .forEach (v = > {if (v.value = = data) v.setAttribute (' selected', true) else v.removeAttribute ('selected')}))
Update innerHTML
The implementation method here is a bit low, only thinking of regular replacement {{text}}.
Let regExpInner = /\ {* ([\ w\ -] +) *\}} / gthis.$el.querySelectorAll ("*") .forEach (I = > {let replaceList = I [XSS _ clean] .match (regExpInner) | (i.hasAttribute ('vueID') & & i.getAttribute (' vueID') .match (regExpInner)) if (replaceList) {if (! i.hasAttribute ('vueID')) {i.setAttribute (' vueID') I [XSS _ clean])} I [XSS _ clean] = i.getAttribute ('vueID') replaceList.forEach (v = > {let key = v.slice (2, v.length-2) I [XSS _ clean] = I [XSS _ clean]. Replace (v, this.$data [key])}})
Listener (watcher)
Update the view after the data changes
Plus what you enter is: {{text1}} + {{text2}} + {{text3}} Volvo Saab Volvo Saab you have chosen: {{select}} let app = new TinyVue ({el:'# app', data: {text1: 123, text2: 456, text3: 'text box', select: 'saab'}, methods: {add () {this.text1 + + this.text2 + +})
All TinyVue codes
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 key models, (I, key, data) = > {i.value = data}) this._initView ('select', 'v house models, (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 [XSS _ clean] .match (regExpInner) | | (i.hasAttribute (' vueID') & & i.getAttribute ('vueID') .match (regExpInner)) if (replaceList) {if (! i.hasAttribute) ('vueID')) {i.setAttribute (' vueID' I [XSS _ clean])} I [XSS _ clean] = i.getAttribute ('vueID') replaceList.forEach (v = > {let key = v.slice (2, v.length-2) I [XSS _ clean] = I [XSS _ clean]. 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 key modelling, (I, key) = > {i.addEventListener ('input', () = > {Object.assign (this.$data, {[key]: i.value})}) this._initEvents (' select', 'v key modelling, (I, key) = > {i.addEventListener ('change') () = > Object.assign (this.$data, {[key]: i.options [i.options.selectedIndex] .value})})}} this is all the content of the article "how to use ES6's class to write a two-way binding" Thank you for reading! I believe you will gain a lot after reading this article. The editor will update different knowledge for you every day. If you want to learn more knowledge, please pay attention to the industry information channel.