html的底层原理,vue底层原理实现.html

Document

{{message}}

class Vue {

constructor(options) {

this.$el = options.el

this.$data = options.data

this.$options = options

new Observer(this.$data)

Object.keys(this.$data).forEach(key => {

this._proxy(key)

})

new Compiler(this.$el, this)

new Computed(this, this.$options);

}

_proxy(key) {

console.log(key);

Object.defineProperty(this, key, {

configurable: true,

enumerable: true,

get() {

return this.$data[key]

},

set(newValue) {

this.$data[key] = newValue

}

})

}

}

class Observer {

constructor(data) {

this.data = data

Object.keys(data).forEach(key => {

this._defineReactive(this.data, key, data[key])

})

}

_defineReactive(data, key, value) {

const dep = new Dep()

Object.defineProperty(data, key, {

configurable: true,

enumerable: true,

get() {

if (Dep.target) {

dep.addSub(Dep.target)

}

return value

},

set(newValue) {

if (newValue === value) {

return

}

value = newValue

dep.notify()

}

})

}

}

class Dep {

constructor() {

this.subs = []

}

addSub(sub) {

this.subs.push(sub)

}

notify() {

this.subs.forEach(sub => {

sub.update()

})

}

}

const mustache = /\{\{(.+)\}\}/

class Compiler {

constructor(el, vm) {

this.el = document.querySelector(el)

this.vm = vm

this.frag = this._createFragment()

this.el.appendChild(this.frag)

}

_createFragment() {

const frag = document.createDocumentFragment()

let child;

while (child = this.el.firstChild) {

this._compile(child)

frag.appendChild(child)

}

return frag

}

_compile(node) {

// console.log(node);

if (node.nodeType === 1) {

const attrs = node.attributes

if (attrs.hasOwnProperty('v-model')) {

const nodeName = attrs['v-model'].nodeValue

node.addEventListener('input', e => {

this.vm[nodeName] = e.target.value

})

}

}

if (node.nodeType === 3) {

if (mustache.test(node.nodeValue)) {

const nodeName = RegExp.$1.trim()

console.log(nodeName);

new Watcher(node, nodeName, this.vm)

}

}

}

}

class Watcher {

constructor(node, key, vm) {

this.node = node

this.key = key

this.vm = vm

Dep.target = this;

this.update()

Dep.target = null

}

update() {

// console.log(this.vm.$data[this.key]);

this.node.nodeValue = this.vm[this.key]

}

}

class Computed {

constructor(vm, options) {

this.vm = vm

this.computed = this.options.computed

Object.keys(computed).forEach(function (key) {

Object.defineProperty(vm, key, {

get: typeof computed[key] === "function" ? computed[key] : computed[key].get,

set() { }

})

})

};

}

const app = new Vue({

el: '#app',

data: {

message: '哈哈哈'

}

})

一键复制

编辑

Web IDE

原始数据

按行查看

历史

你可能感兴趣的:(html的底层原理)