之前的文章《一文了解vue中watcher数据双向绑定原理(附代码)》中,给大家介绍了解了vue中complie数据双向绑定原理。下面本篇文章给大家了解vue中complie数据双向绑定原理,伙伴们过来看看吧。
vue数据双向绑定原理,和简单的实现,本文将实现mvvm的模板指令解析器
1)vue数据双向绑定原理-observer
2)vue数据双向绑定原理-observer
立即学习“前端免费学习笔记(深入)”;
3)vue数据双向绑定原理-observer
vue数据双向绑定原理,和简单的实现,本文将实现mvvm的模板指令解析器
上一步实现了简单数据绑定,最后实现解析器,来解析v-model,v-on:click等指令,和{{}}模板数据。解析器Compile实现步骤:
解析模板指令,并替换模板数据,初始化视图
将模板指令对应的节点绑定对应的更新函数,初始化相应的订阅器
为了解析模板,首先需要获取到dom元素,然后对含有dom元素上含有指令的节点进行处理,因此这个环节需要对dom操作比较频繁,所有可以先建一个fragment片段,将需要解析的dom节点存入fragment片段里再进行处理:
function node2Fragment(el) { var fragment = document.createDocumentFragment(), child; // 将原生节点拷贝到fragment while ((child = el.firstChild)) { fragment.appendChild(child); } return fragment;}
登录后复制
接下来渲染'{{}}’模板
//Compilefunction Compile(el, vm) { this.$vm = vm; this.$el = this.isElementNode(el) ? el : document.querySelector(el); if (this.$el) { this.$fragment = this.node2Fragment(this.$el); this.init(); this.$el.appendChild(this.$fragment); }}Compile.prototype = { init: function () { this.compileElement(this.$fragment); }, node2Fragment: function (el) { //... }, //编译模板 compileElement: function (el) { var childNodes = el.childNodes, self = this; [].slice.call(childNodes).forEach(function (node) { var text = node.textContent; var reg = /{{(.*)}}/; //表达式文本 //按元素节点方式编译 if (self.isElementNode(node)) { self.compile(node); } else if (self.isTextNode(node) && reg.test(text)) { self.compileText(node, RegExp.$1); } //遍历编译子节点 if (node.childNodes && node.childNodes.length) { self.compileElement(node); } }); }, isElementNode: function (node) { return node.nodeType == 1; }, isTextNode: function (node) { return node.nodeType == 3; }, compileText: function (node, exp) { var self = this; var initText = this.$vm[exp]; this.updateText(node, initText); new Watcher(this.$vm, exp, function (value) { self.updateText(node, value); }); }, updateText: function (node, value) { node.textContent = typeof value == "undefined" ? "" : value; },};
登录后复制
处理解析指令对相关指令进行函数绑定。
Compile.prototype = { ...... isDirective: function(attr) { return attr.indexOf('v-') == 0; }, isEventDirective: function(dir) { return dir.indexOf('on:') === 0; }, //处理v-指令 compile: function(node) { var nodeAttrs = node.attributes, self = this; [].slice.call(nodeAttrs).forEach(function(attr) { // 规定:指令以 v-xxx 命名 // 如 中指令为 v-text var attrName = attr.name; // v-text if (self.isDirective(attrName)) { var exp = attr.value; // content var dir = attrName.substring(2); // text if (self.isEventDirective(dir)) { // 事件指令, 如 v-on:click self.compileEvent(node, self.$vm, exp, dir); } else { // 普通指令如:v-model, v-html, 当前只处理v-model self.compileModel(node, self.$vm, exp, dir); } //处理完毕要干掉 v-on:, v-model 等元素属性 node.removeAttribute(attrName) } }); }, compileEvent: function(node, vm, exp, dir) { var eventType = dir.split(':')[1]; var cb = vm.$options.methods && vm.$options.methods[exp]; if (eventType && cb) { node.addEventListener(eventType, cb.bind(vm), false); } }, compileModel: function(node, vm, exp, dir) { var self = this; var val = this.$vm[exp]; this.updaterModel(node, val); new Watcher(this.$vm, exp, function(value) { self.updaterModel(node, value); }); node.addEventListener('input', function(e) { var newValue = e.target.value; if (val === newValue) { return; } self.$vm[exp] = newValue; val = newValue; }); }, updaterModel: function(node, value, oldValue) { node.value = typeof value == 'undefined' ? '' : value; },}
登录后复制
最后再关联起来
function Vue(options) { ..... observe(this.data, this); this.$compile = new Compile(options.el || document.body, this) return this;}
登录后复制
来尝试下效果
new Vue({ el: "#app", data: { name: "chuchur", age: 29, }, methods: { test() { this.name = "My name is chuchur"; }, }, });{{name}}
{{name}}
登录后复制
OK. 基本完善了
推荐学习:vue数据双向绑定原理-observer
以上就是浅析vue中complie数据双向绑定原理(代码详解)的详细内容,更多请关注【创想鸟】其它相关文章!
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至253000106@qq.com举报,一经查实,本站将立刻删除。
发布者:PHP中文网,转转请注明出处:https://www.chuangxiangniao.com/p/3020026.html