import Vue from './instance/index'
import { initGlobalAPI } from './global-api/index'
import { isServerRendering } from 'core/util/env'
import { FunctionalRenderContext } from 'core/vdom/create-functional-component'
// Mount various methods for Vue
initGlobalAPI(Vue)
/ / to redefine $isServer, $sseContext, FunctionalRenderContext
Object.defineProperty(Vue.prototype,'$isServer', {get:isServerRendering Prototype.$isServer to determine if the prototype is currently an SSR render
})
Object.defineProperty(Vue.prototype,'$ssrContext', {get(){ // Get the current context with vue.prototype. $ssrContext
    return this.$vnode && this.$vnode.ssrContext
  }
})
// Vue.FunctionalRenderContext = {value:FunctionalRenderContext}
Object.defineProperty(Vue,'FunctionalRenderContext', {value:FunctionalRenderContext
})
Vue.version = '__VERSION__'
export default Vue
Copy the code

isServerRendering

let _isServer
export const isServerRendering = () = > {
  if(_isServer === undefined) {// Mark non-wechat environment, non-browser environment,node environment, according to Vue environment variables to determine whether it is SSR
    if(! isBrowser && ! inWeex &&typeof global! = =undefined){
      _isServer = global['process'] && global['process'].env.VUE_ENV === 'server'
    }else{
      _isServer = false}}}Copy the code

FunctionalRenderContext

export function FunctionalRenderContext(data,props,children,parent,Ctor){
  const options = Ctor.options
  let contextVm
  if(hasOwn(parent,'_uid')){
    contextVm = Object.create(parent)
    contextVm._original = parent
  }else{
    contextVm = parent
    parent = parent._original
  }
  const isCompiled = isTrue(options._compiled)
  constneedNormalization = ! isCompiled// 
  this.data = data
  this.props = props
  this.children = children
  this.parent = parent
  this.listeners = data.on || emptyObject
  // Mount the current injection
  this.injections = resolveInject(options.inject,parent)
  // Outputs all slots on the child component and serializes all slots to scopeSlots if none exist
  this.slots = () = > {
    if(!this.$slots){
      // Serialize all slots and save to data.scopeslots
      normalizeScopeSlots(
        data.scopeSlots,
        this.$slots = resolveSlots(children,parent) // Get all slots on the child component)}return this.$slots
  }
  // this.scopedSlots = serialized slots
  Object.define(this.'scopedSlots', ({enumerable: true.get(){
      return normalizeScopedSlots(data.scopeSlots,this.slots())
    }
  })
  if(isCompiled){
    this.$options = options
    this.$slots = this.slots()
    this.$scopedSlots = normalizeScopedSlots(data.scopedSlots,this.$slots)
  }
  if(options._scopeId){
    this._c = (a,b,c,d) = >{
      // Outputs the virtual node
      const vnode = createElement(contextVm,a,b,c,d,needNormalization)
      if( vnode && !Array.isArray(vnode)){
        vnode.fnScopeId = options._scopeId
        vnode.fnContext = parent
      }
      return vnode
    }
  }else{
    this._c = (a,b,c,d) = > createElement(contextVm,a,b,c,d,needNormalization)
  }
}
Copy the code

createElement

export function createElement(context,tag,data,children,normalizationType,alwaysNormalize){
  if(Array.isArray(data) || isPrimitive(data)){
    normalizationType = children
    children = data
    data = undefined
  }
  if(isTrue(alwaysNormalize)){
    normalizationType = ALWAYS_NORMALIZE
  }
  return _createElement(context,tag,data,children,normalizationType)
}
export function _createElement(context,tag,data,children,normalizationType){
  if(isDef(data) && isDef(data.__ob__)){
    ... // When the data of the vNode construction is observed, return the empty VNode
  }
  // When using components, use is as the label
  if(isDef(data) && isDef(data.is)){
    tag = data.is
  }
  // If the label does not exist, empty vNode is returned
  if(! tag){return createEmptyVNode()
  }
  ... // Processing for non-raw keys
  // Support operations whose child component is function
  if(Array.isArray(children) && typeof children[0= = ='function'){
    data = data || {}
    data.scopedSlots = { default: children[0] }
    children.length = 0
  }
  // sequence the child node
  if(normalizeType === ALWAYS_NORMALIZE){
    children = normalizeChildren(children)
  }else if(normalizeType === SIMPLE_NORMALIZE){
    children = simpleNormalizeChildren(children)
  }
  let vnode,ns
  if(typeof tag === 'string') {let Ctor
    ns = (context.$vnode && context.$vnode.ns) || config.getTagNameSpace(tag)
    if(config.isReservedTag(tag)){
      ...// Add native modifiers only for component tag warnings
      vnode = new VNode(config.parsePlatformTagName(tag),data,children,null.null,context)
    }else if((! data || ! data.pre) && isDef(Ctor = resolveAsset(context.$options,'components',tag))){
      // Look for the presence of the label in the imported component
      // Create a VNode based on the component configuration
      vnode = createComponent(Ctor,data,context,children,tag)
    }else{
      / / create a vnode
      vnode = new VNode(tag,data,children,undefined.undefined,context)
    }
  }else{
    vnode = createComponent(tag,data,context,children)
  }
  if(Array.isArray(vnode)){
    return vnode
  }else if(isDef(vnode)){
    // Mount ns for vNode, register style and class on data
    if(isDef(ns)) applyNs(vnode,ns)
    if(isDef(data)) registerDeepBindings(data)
    return vnode
  }else{
    // VNode does not return an empty node
    return createEmptyVNode()
  }
}
Copy the code

createComponent

export function createComponent(Ctor,data,context,children,tag){
  // Return if the label is null or undefined
  if(isUndef(Ctor)){
    return
  }
  const baseCtor = Ctor.$options._base
  if(isObject(Ctor)){
    Ctor = baseCtor.extend(Ctor)
  }
  // Check if Ctor is not a constructor or component factory
  if(typeofCtor ! = ='function'){
    ...
  }
  let asyncFactory
  if(isUndef(Ctor.cid)){
    asyncFactory = Ctor
    // Returns the component's constructor
    Ctor = resolveAsyncComponent(asyncFactory,baseCtor)
    if(Ctor === undefined) {// Returns an empty node
      return createAsyncPlaceholder(asyncFactory,data,context,children,tag,)
    }
  }
  data = data || {}
  // Parse the Ctor configuration
  resolveConstructorOptions(Ctor)
  // Parse the V-Model, events/properties/callbacks
  if(isDef(data.model)){
    transformModel(Ctor.options,data)
  }
  // Mount prop for data
  const propsData = extractPropsFormVNodeData(data,Ctor,tag)
  if(isTrue(Ctor.options.functional)){
    // Generate functional components
    return createFunctionalComponent(Ctor,propsData,data,context,children)
  }
  // Define mounted events/native events/slots
  const listeners = data.on
  data.on = data.nativeOn
  if(isTrue(Ctor.options.abstract)){
    const slot = data.slot
    data = {}
    if(slot){
      data.slot = slot
    }
  }
  // Mount the component's hook function
  installComponentHooks(data)
  / / generated vnode
  const name = Ctor.options.name || tag
  const vnode = new VNode(`vue-component-${Ctor.cid}${name ? ` -${name}`:' '}`,data,undefined.undefined.undefined,context,{Ctor,propsData,listeners,tag,children},asyncFactory)
  ...
  return vnode
}
Copy the code

resolveInject

export function resolveInject(inject,vm){
  if(inject){
    const result = Object.create(null)
    const keys = hasSymbol ? Reflect.ownKeys(inject) : Object.keys(inject)
    // Processing for injection
    for(let i = 0; i < keys.length; i ++){
      const key = keys[i]
      if(key === '__ob__') continue
      // Get the source of the injected parent node
      const provideKey = inject[key].from 
      let source = vm
      // Get the injected method or property from the parent node
      while(source){
        if(source._provided && hasOwn(source._provided,providedKey)){
          result[key] = source._provided[providedKey]
          break
        }
        source = source.$parent
      }
      // If the parent node does not exist, it is obtained according to the injected property
      if(! source){if('default' in inject[key]){
          const provideDefault = inject[key].default
          result[key] = typeof provideDefault === 'function' ? provideDefault.call(vm) : provideDefault
        }else if(process.env.NODE_ENV ! = ='production'){
          warn(`Injection "${key}" not found`,vm)
        }
      }
    }
    return result
  }
}
Copy the code