当前位置: 首页 > Web前端 > vue.js

JS实现Vue

时间:2023-03-31 22:01:14 vue.js

vue的简单使用。相信大家都不陌生,而且简单易用。但是大多数人并不知道它的内部原理是怎样的。今天我们一起来实现一个简单的vue。在Object.defineProperty()实现之前,我们得先看看Object.defineProperty的实现,因为Vue主要是通过数据劫持来实现的,数据的读取和更新都是通过get和set来完成的。从上面可以看出,通过get获取数据,通过set监听数据变化,进行相应的操作。如果还是不明白,可以去看Object.defineProperty文档。流程图js调用Vue结构1、Vueconstructor构造函数主要是数据初始化2、proxyData数据代理3、observer劫持监听所有数据4、compile解析dom5、compileText解析dom处理纯双花括号操作6、Watcher更新View操作vue构造器初始化上面主要是一个初始化操作,处理传入的数据proxyData代理数据上面主要是把数据代理到顶层,http://this.xxx直接访问...observer劫持监控也是用到Object.defineProperty监听数据,初始化需要订阅的数据。将需要订阅的数据推送到watcherTask,需要更新的时候再批量更新数据。?以下是;遍历订阅池,批量更新视图。compile解析domclassVue{constructor(options={}){......}proxyData(key){......}observer(data){......}compile(el){var节点=el.childNodes;for(leti=0;i0){this.compile(node)}if(node.hasAttribute('v-model')&&(node.tagName==='INPUT'||node.tagName==='TEXTAREA')){node.addEventListener('input',(()=>{letattrVal=node.getAttribute('v-model')this.watcherTask[attrVal].push(newWatcher(node,this,attrVal,'value'))node.removeAttribute('v-model')return()=>{this.data[attrVal]=node.value}})())}if(node.hasAttribute('v-html')){letattrVal=node.getAttribute('v-html');this.watcherTask[attrVal].push(newWatcher(node,this,attrVal,'innerHTML'))node.removeAttribute('v-html')}this.compileText(node,'innerHTML')if(node.hasAttribute('@click')){letattrVal=node.getAttribute('@click')node.removeAttribute('@click')node.addEventListener('click',e=>{this.methods[attrVal]&&this.methods[attrVal].bind(this)()})}}}},compileText(node,type){让reg=/{{(.*)}}/g,txt=node.textContent;if(reg.test(txt)){node.textContent=txt.replace(reg,(matched,value)=>{让tpl=this.watcherTask[value]||[]tpl.push(newWatcher(node,this,value,type))returnvalue.split('.').reduce((val,key)=>{returnthis.data[key];},this.$el);})}}}有这里有很多代码,我们分解一下,你会发现它很简单。首先我们遍历el元素下的所有子节点,node.nodeType===3表示当前元素是文本节点,node.nodeType===1表示当前元素是元素节点因为有些可能是明文形式,比如纯双花括号是明文的文本节点,然后判断元素节点是否还有子节点,如果有,则递归调用compile方法。重头戏来了,我们拆开看看:上面先判断node节点上有没有v-html之类的命令,如果有,我们就发布订阅,如何发布订阅呢?只需要将需要订阅的数据push到watcherTask,然后在设置value的时候就可以批量更新,实现双向数据绑定,即下面的操作和push的value是一个实例守望者。首先,它new的时候,会先执行一次,执行的操作是把纯双花括号改成->1,也就是把我们写的模板数据更新到模板视图中。最后,删除当前元素属性。我们在使用Vue的时候是看不到这种指令的。如果我们不删除它,它不会影响它。就是把当前元素比如:node.innerHTML='thisisthevalueindata',node.value='thisisthedataoftheform'那我们直接更新不就行了,还有什么我们需要更新吗,这不是多余的吗?事实上,你还记得更新吗?我们需要通过调用Watcher原型上的update方法来批量更新订阅池。效果你可以在浏览器中查看效果,因为我太懒了,我就不放gif效果图了,哈哈??完整代码地址:https://github.com/wclimb/MyVue参考1.Vue原理&实现分析双向绑定MVVM2,仿Vue实现极简双向绑定微信公众号:我的web前端自学-helproad回复进群,一起和大佬交流技术