因为工做中常用vue,因此对它的内部构造很是着迷,一直想探究其究竟。也看了很多文章,无奈水平所限并不能吃透、看透。因此运用目前本身所学,写了demo,本demo总共100行左右,实现v-model,v-bind,v-click等功能。javascript
因为水平所限,本demo写的不是很规范,考虑的不是很周全,程序设计不太合理。只能实现基本的功能,做为学习的一个记录。还但愿大神勿喷,欢迎批评指正。vue
第一次写博客,语言组织能力有待增强。java
一、HTML部分 node
<div id="app"> <span style="display: inline-block" v-bind="num"></span> <span style="display: block" v-bind="input"></span> <span style="display: block" v-bind="test"></span> <span style="display: block" v-bind="input2"></span> <input style="display: block" type="text" v-model="input"> <input style="display: block" type="text" v-model="test"> <input style="display: block" type="text" v-model="input2"> <button @click="handleClick">click</button> </div>
二、javascript部分app
<script>
function Vue (options) {
this.initValue = Object.assign({},options.data) this.data = options.data this.methods = options.methods this.el = document.getElementById(options.el) this.bindList = [] this._init(this.el) } Vue.prototype._init = function (d) { this.render(d.children) this.definedProprtyInt (this.data) } //遍历dom树 Vue.prototype.render =function (nodeList) { Array.prototype.forEach.call(nodeList,(item) => { let childNode = item.children let len = childNode.length //匹配v-model或者@model let model = item.getAttribute('v-model')||item.getAttribute('@model') let type = item.tagName.toLocaleLowerCase() if (model) { item.value = this.initValue[model] this.data[model] = "" if (type === 'input') { item.onkeyup = function (e) { this.data[model] = e.target.value }.bind(this) } } //匹配v-bind 并绑定相应的值 let bind = item.getAttribute('v-bind')||item.getAttribute('@bind') if(bind && (bind in this.data)) { //收集依赖 item.innerHTML = this.initValue[bind] this.bindList.push({ key:bind, d:item }) } //匹配v-click或者@click let eventName = item.getAttribute('v-click')||item.getAttribute('@click') if(eventName) { item.onclick = function (e) { this.methods[eventName].bind(this.data)(e) }.bind(this) } if(len>0) { this.render(childNode) } },this) } Vue.prototype.definedProprtyInt = function (o){ let _this = this for(let key in o) { Object.defineProperty(o,key,{ set:function (v) { //在data中找到相应的key渲染到对应的页面上 this.bindList.forEach((item) => { if(key == item.key) { item.d.innerHTML = v } }) _this.initValue[key] = v }.bind(this), get:function (v) { // console.log(_this.initValue[key]) return _this.initValue[key] }, }) } } new Vue({ el:"app", data:{ input:"input", test:"test", input2:"input2", num:1 }, methods:{ handleClick:function (e) { this.num ++ } } }) </script>