浅析vue中的MVVM实现原理
更新时间:2019年03月04日 10:36:13 作者:一席蓑衣笑众
这篇文章主要介绍了浅析vue中的MVVM实现原理,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
现成MVVM
菜单教程
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Vue 测试实例 - 菜鸟教程(runoob.com)</title> <script src="https://unpkg.com/vue/dist/vue.js"></script> </head> <body> <div id="app"> <input type="text" v-model="message"> <p>{{ message }}</p> </div> <script> let vm = new Vue({ el: '#app', data: { message: 'Hello Vue.js!' } }) </script> </body> </html>
视图影响数据
数据影响视图
项目构架
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> </head> <body> </body> </html> <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Vue 测试实例 - 菜鸟教程(runoob.com)</title> <script src="./js/mvvm.js"></script> <script src="./js/compile.js"></script> </head> <body> <div id="app"> <input type="text" v-model="message"> <div>{{message}}</div> <ul> <li></li> </ul> {{message}} </div> <script> let vm = new MVVM({ el: '#app', data: { message: 'Hello Vue.js!' } }) </script> </body> </html>
mvvm.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> </head> <body> </body> </html> <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Vue 测试实例 - 菜鸟教程(runoob.com)</title> <script src="./js/mvvm.js"></script> <script src="./js/compile.js"></script> </head> <body> <div id="app"> <input type="text" v-model="message"> <div>{{message}}</div> <ul> <li></li> </ul> {{message}} </div> <script> let vm = new MVVM({ el: '#app', data: { message: 'Hello Vue.js!' } }) </script> </body> </html>
mvvm.js
class MVVM { constructor(options) { this.$el = options.el; this.$data = options.data; if (this.$el) { new Compile(this.$el); } } }
compile把dom节点,放在内存中操作(到35分钟)
class Compile { constructor(el, vm) { this.el = this.isElementNode(el) ? el : document.querySelector(el); this.vm = vm; if (this.el) { let fragment = this.node2frament(this.el); this.compile(fragment); } } //辅助方法 isElementNode(node) { return node.nodeType === 1; } //核心方法 compile(fragment) { let childNodes = fragment.childNodes; console.log(childNodes) } node2frament(el) { let fragment = document.createDocumentFragment(); let firstChild; while (firstChild = el.firstChild) { fragment.appendChild(firstChild); } return fragment } }
分类元素节点和文本节点(52分钟)
class Compile { constructor(el, vm) { this.el = this.isElementNode(el) ? el : document.querySelector(el); this.vm = vm; if (this.el) { let fragment = this.node2frament(this.el); this.compile(fragment); } } //辅助方法 isElementNode(node) { return node.nodeType === 1; } isDirective(name) { return name.includes('v-') } //核心方法 compileElement(node) { let attrs = node.attributes; Array.from(attrs).forEach(arrt => { let attrName = attr.name; if (this.isDirective(attrName)) { let expr = attr.value; } }) } compileText(node) { let text = node.textContent; let reg = /\{\{([^}]+)\}\}/g; if (reg.test(text)) { } } compile(fragment) { let childNodes = fragment.childNodes; Array.from(childNodes).forEach(node => { if (this.isElementNode(node)) { this.compile(node) } else { console.log('text', node) } }) } node2frament(el) { let fragment = document.createDocumentFragment(); let firstChild; while (firstChild = el.firstChild) { fragment.appendChild(firstChild); } return fragment } }
元素节点
文本节点
把data中的数据,显示在视图上(到1:16分)
class Compile { constructor(el, vm) { this.el = this.isElementNode(el) ? el : document.querySelector(el); this.vm = vm; if (this.el) { let fragment = this.node2frament(this.el); this.compile(fragment); this.el.appendChild(fragment) } } //辅助方法 isElementNode(node) { return node.nodeType === 1; } isDirective(name) { return name.includes('v-') } //核心方法 compileElement(node) { let attrs = node.attributes; Array.from(attrs).forEach(attr => { let attrName = attr.name; if (this.isDirective(attrName)) { let expr = attr.value; let [, type] = attrName.split('-'); CompileUtil[type](node, this.vm, expr) } }) } compileText(node) { console.log(node) let expr = node.textContent; let reg = /\{\{([^}]+)\}\}/g; if (reg.test(expr)) { CompileUtil['text'](node, this.vm, expr) } } compile(fragment) { let childNodes = fragment.childNodes; Array.from(childNodes).forEach(node => { if (this.isElementNode(node)) { this.compileElement(node) this.compile(node) } else { this.compileText(node) } }) } node2frament(el) { let fragment = document.createDocumentFragment(); let firstChild; while (firstChild = el.firstChild) { fragment.appendChild(firstChild); } return fragment } } CompileUtil = { getVal(vm, expr) { // 获取实例上对应的数据 expr = expr.split('.'); // [message,a] return expr.reduce((prev, next) => { // vm.$data.a return prev[next]; }, vm.$data); }, getTextVal(vm, expr) { // 获取编译文本后的结果 return expr.replace(/\{\{([^}]+)\}\}/g, (...arguments) => { return this.getVal(vm, arguments[1]); }) }, text(node, vm, expr) { //文本处理 let updateFn = this.updater['textUpdater']; let value = this.getTextVal(vm, expr); updateFn && updateFn(node, value) }, model(node, vm, expr) { let updateFn = this.updater['modelUpdater']; updateFn && updateFn(node, this.getVal(vm, expr)); }, updater: { textUpdater(node, value) { node.textContent = value; }, modelUpdater(node, value) { node.value = value; } } }
v-model类型
modelUpdater(node, value) { node.value = value; console.log(node) console.log(value) console.log(node.value) }
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。
相关文章
解决vue项目,npm run build后,报路径错的问题
这篇文章主要介绍了解决vue项目,npm run build后,报路径错的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧2020-08-08vue中axios给后端传递参数出现等于号和双引号的问题及解决方法
这篇文章主要介绍了vue中axios给后端传递参数出现等于号和双引号要怎么解决,项目场景我是传递一个string字符给后端时候报错,随手把这个问题记录下来了,需要的朋友可以参考下解决方案2022-11-11antd Select下拉菜单动态添加option里的内容操作
这篇文章主要介绍了antd Select下拉菜单动态添加option里的内容操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧2020-11-11element-ui vue input输入框自动获取焦点聚焦方式
这篇文章主要介绍了element-ui vue input输入框自动获取焦点聚焦方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教2023-04-04vue2 如何实现div contenteditable=“true”(类似于v-model)的效果
这篇文章主要给大家介绍了利用vue2如何实现div contenteditable="true",就是类似于v-model的效果,文中给出了两种解决的思路,对大家具有一定的参考价值,有需要的朋友们下面来一起看看吧。2017-02-02
最新评论