function Vue(options){
if(process.env.NODE_ENV !== 'production' && !(this instanceof Vue)){
warn('Vue is a constructor ans shold be called with the `new` keyword')
}
this._init(options)
}
initMixin(Vue)
stateMixin(Vue)
eventsMixin(Vue)
lifecycleMixin(Vue)
renderMixin(Vue)
export default Vue
initMixin
let uid = 0
export function initMixin(Vue){
Vue.prototype._init = function(options){
const vm = this
vm._uid = uid ++
let startTag,endTag
if(process.env.NODE_ENV !== 'production' && config.performance && mark){
startTag = `vue-perf-start:${vm._uid}`
endTag = `vue-perf-end:${vm._uid}`
mark(startTag)
}
vm._isVue = true
if(options && options._isComponent){
initInternalComponent(vm,options)
}else{
vm.$options = mergeOptions(resolveConstructorOptions(vm.constructor),options || {},vm)
}
if(process.env.NODE_ENV !== 'production'){
initProxy(vm)
}else{
vm._renderProxy = vm
}
vm._self = vm
initLifyCycle(vm)
initEvents(vm)
initRender(vm)
callHook(vm,'beforeCreate')
initInjections(vm)
initState(vm)
initProvide(vm)
callHook(vm,'created')
if(process.env.NODE_ENV !== 'production' && config.performance && mark){
vm._name = formatComponentName(vm,false)
mark(endTag)
measure(`vue ${vm._name} init`,startTag,endTag)
}
if(vm.$options.el){
vm.$mount(vm.$options.el)
}
}
}
stateMixin
export function stateMixin(Vue){
const dataDef = {}
dataDef.get = function(){ return this._data }
const propsDef = {}
propsDef.get = function(){ return this._props }
...
Object.defineProperty(Vue.property,'$data',dataDef)
Object.defindeProperty(Vue.property,'$props',propsDef)
Vue.prototype.$set = set
Vue.prototype.$del = del
Vue.prototype.$watch = function(expOrFn,cb,options){
const vm = this
if(isPlainObject(cb)){
return createWatcher(vm,expOrFn,cb,options)
}
options = options || {}
options.user = true
const watcher = new Watcher(vm,expOrFn,cb,options)
if(options.immediate){
pushTarget()
try{
cb.call(vm,watcher.value)
}catch(error){
handleError(error,vm,`callback for immediate watcher "${watcher.expression}"`)
}
popTarget()
}
return function unwatchFn(){
watcher.teardown()
}
}
}
eventsMixin
export function eventsMixin(Vue){
const hookRE = /^hook:/
Vue.prototype.$on = function(event,fn){...}
Vue.prototype.$once = function(event,fn){
const vm = this
function on(){
vm.$off(event,on)
fn.apply(vm,argument)
}
on.fn = fn
vm.$on(event,on)
return vm
}
Vue.prototype.$off = function(event,fn){...}
Vue.prototype.$emit = function(event){
const vm = this
...
let cbs = vm._events[event]
if(cbs){
cbs = cbs.length > 1 ? toArray(cbs) : cbs
const args = toArray(arguments,1)
const info = `event handler for ${event}`
for(let i = 0,l = cbs.length; i < l; i ++){
invokeWithErrorHandling(cbs[i],vm,args,vm,info)
}
}
return vm
}
}
lifecycleMixin
export function lifecycleMixin(Vue){
Vue.prototype._update = function(vnode,hydrating){
const vm = this
const prevEl = vm.$el
const prevVnode = vm._vnode
const restoreActiveInstance = setActiveInstance(vm)
vm._vnode = vnode
if(!prevVnode){
vm.$el = vm.__patch__(vm.$el,vnode,hydrating,false)
}else{
vm.$el = vm.__patch__(prevVnode,vnode)
}
restoreActiveInstance()
if(prevEl){
prevEl.__vue__ = null
}
if(vm.$el){
vm.$el.__vue__ = vm
}
if(vm.$vnode && vm.$parent && vm.$vnode === vm.$parent._vnode){
vm.$parent.$el = vm.$el
}
}
Vue.prototype.$forceUpdate = function(){
const vm = this
if(vm._watcher){
vm._watcher.update()
}
}
Vue.prototype.$destroy = function(){
const vm = this
if(vm._isBeingDestroyed){
return
}
callHook(vm,'beforeDestroy')
vm._isBeingDestroyed = true
const parent = vm.$parent
if(parent && !parent._isBeingDestroyed && !vm.$options.abstract){
remove(parent.$children,vm)
}
if(vm._watcher){
vm._watcher.teardown()
}
let i = vm._watchers.length
while(i --){
vm._watchers[i].teardown()
}
if(vm._data.__ob__){
vm._data.__ob__.vmCount --
}
vm._isDestroyed = true
vm.__patch__(vm._vnode,null)
callHook(vm,'destroyed')
vm.$off()
if(vm.$el){
vm.$el.__vue__ = null
}
if(vm.$vnode){
vm.$vnode.parent = null
}
}
}
renderMixin
export function renderMixin(Vue){
installRenderHelpers(Vue.prototype)
Vue.prototype.$nextTick = function(fn){
return nextTick(fn,this)
}
Vue.prototype._render = function(){
cosnt vm = this
const { render, _parentVnode } = vm.$options
if(_parentVnode){
vm.$scopedSlots = normalizeScopedSlots(_parentVnode.data.scopedSlots,vm.$slots,vm.$scopedSlots)
}
vm.$vnode = _parentVnode
let vnode
try{
currentRenderingInstance = vm
vnode = render.call(vm._renderProxy,vm.$createElement)
}catch(e){
hanleError(e,vm,'render')
if(process.env.NODE_ENV !== 'production' && vm.$options.renderError){
try{
vnode = vm.$options.renderError.call(vm._renderProxy,vm.$createElement,e)
}catch(e){
handleError(e,vm,'renderError')
vnode = vm._vnode
}
}else{
vnode = vm._vnode
}
}finally{
currentRenderingInstance = null
}
if(Array.isArray(vnode) && vnode.length === 1){
vnode = vnode[0]
}
if(!vnode instanceof VNode){
if(process.env.NODE_ENV !== 'production' && Array.isArray(vnode)){
warn(
'Multiple root nodes returned from render function. Render function should return a single root node',vm
)
}
vnode = creatEmptyVNode()
}
vnode.parent = _parentVnode
return vnode
}
}