-
Notifications
You must be signed in to change notification settings - Fork 5
13.VM 构造函数
wushufen edited this page May 29, 2019
·
1 revision
- 把
options.data
的数据拷到vm
- 对
methods
注入vm.$render
并拷到vm
- 对
mouted
等注入vm.$render
-
compile
编译模板生成render
-
createVnode
,each
放到原型传入render
-
vm.$render
里进行异步dom diff
- 如果支持
Proxy
则使用返回的是proxy
方便在在控制台调试 - 如
vm.$el
存在,则关联其到dom diff
,并初始渲染
// VM class
function VM(options) {
var vm = this
vm.$options = options || (options = {})
// data
var data = options.data
if (typeof data === 'function') data = data.call(vm) // compoment data()
assign(vm, data)
// methods
each(options.methods, function (fn, key) {
vm[key] = injectRender(vm, fn)
})
// hooks
each(options, function (fn, key) {
if (typeof fn === 'function') {
vm[key] = injectRender(vm, fn)
}
})
// $el
if (options.el) {
vm.$el = options.el
}
// tpl
var tplNode = options.el
if (options.template) {
tplNode = parse(options.template)
}
// render: options.render || compile
var render = options.render
if (!render) {
tplNode = tplNode || {}
render = options.render = compile(tplNode)
}
// async render
vm.$render = function () {
// update computed
// each(options.computed, function (fn, key) {
// vm[key] = fn.call(vm)
// })
// trigger watch
// dom diff update view
cancelAnimationFrame(render.timer)
render.timer = requestAnimationFrame(function () {
var vnode = options.__vnode = render.call(vm, createElement)
if (vm.$el) {
diff(vm.$el, vnode)
}
})
}
// async call hooks
requestAnimationFrame(function () {
// created hook
vm.created && vm.created()
// $mount
if (vm.$el) {
vm.$mount(vm.$el)
}
})
// test: return proxy
if (typeof Proxy === 'function') {
return new Proxy(vm, {
set: function (vm, key, val) {
vm[key] = val
vm.$render()
},
get: function (vm, key) {
vm.$render()
return vm[key]
}
})
}
}
var __createVnode = createVnode
var __each = each
VM.prototype = {
constructor: VM,
__createVnode: __createVnode,
__each: __each,
$mount: function (el) {
this.$el = el
// render first
this.$render()
// mounted hook
this.mounted && this.mounted()
}
}
VM.options = {
directives: {}
}