因爲工做中常用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>