class MyVue { constructor(options) { this.$el = document.querySelector(options.el) this.$data = options.data this.$methods = options.methods this.init() this.compile(this.$el) } compile (node) { let that = this node.childNodes.forEach(item => { if (item.nodeType == 1) { for (let i = 0; i < item.attributes.length; i++) { if (Array.from(item.attributes).some(items => items.localName.startsWith('@'))) { const attrNode = item.attributes[i] if (attrNode.localName.startsWith('@')) { const evname = attrNode.localName.slice(1) item['on' + evname] = this[item.getAttribute('@' + evname).trim()].bind(this) } } } if (item.hasAttribute('vModel') && item.tagName == 'INPUT') { const dataProp = item.getAttribute('vModel').trim() item.value = this[dataProp] if (!item.SecondAddEventListener) { item.SecondAddEventListener = true item.addEventListener('input', (e) => { this[dataProp] = e.target.value }) } } Array.from(item.attributes).filter(entry => entry.localName !== 'vmodel' && !entry.localName.startsWith('@')).forEach(entry => { if (entry.localName.startsWith('disabled')) { if (entry.localName == 'disabled') { const dataName = item.getAttribute('disabled').trim() if (!that[dataName]) { item.disabled = false item.setAttribute('disabledfalse', dataName) } } else { const dataName = item.getAttribute('disabledfalse') if (that[dataName]) { item.setAttribute('disabled', dataName) } } } else { const dataName = item.getAttribute(entry.localName).trim() item.setAttribute(entry.localName, that[dataName] == undefined ? dataName : that[dataName]) } }) if (item.childNodes.length > 0) { this.compile(item) } } if (item.nodeType == 3) { let text if (item.isSecondMatch) { text = item.FirstContent } else { text = item.textContent.trim() item.FirstContent = text } const reg = /\{\{(.*?)\}\}/g const newText = text.replace(reg, (_, b) => { item.isSecondMatch = true return this.$data[b] }) item.textContent = newText } }) } init () { const vm = this const obj = Object.assign(vm.$data, vm.$methods) for (let k in obj) { Object.defineProperty(vm, k, { get () { if (typeof vm.$methods[k] == 'function') return vm.$methods[k] return vm.$data[k] }, set (newVal) { vm.$data[k] = newVal vm.compile(vm.$el) } }) } } }