vue中初始化

这篇具有很好参考价值的文章主要介绍了vue中初始化。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

初始化流程

initGlobalAPI处理流程

主要是挂载一些全局方法

  • 响应数据相关的Vue.set, Vue.delete, Vue.nextTick以及Vue.observable
  • 插件相关的Vue.use
  • 对象合并相关Vue.mixin
  • 类继承相关的Vue.extend
  • 资源相关,如组件,过滤器,自定义指令Vue.component, Vue.filter, Vue.directive
  • 配置相关Vue.config以及Vue.options中的components,filters,directives

定义属性config

给Vue对象添加config属性,其中config是在src/core/config.ts文件中导出的

const configDef: Record<string, any> = {}
configDef.get = () => config
Object.defineProperty(Vue, 'config', configDef)

挂载util

主要是将src/core/util下的一些方法放到Vue的util属性中

import {
  warn,
  extend,
  nextTick,
  mergeOptions,
  defineReactive
} from '../util/index'

 Vue.util = {
    warn,
    extend,
    mergeOptions,
    defineReactive
  }

挂载响应式相关方法

设置Vue.set,Vue.delete,Vue.nextTick以及Vue.observable方法

import { set, del } from '../observer/index'
import {
  nextTick
} from '../util/index'
import { observe } from 'core/observer/index'
  Vue.set = set
  Vue.delete = del
  Vue.nextTick = nextTick

  // 2.6 explicit observable API
  Vue.observable = <T>(obj: T): T => {
    observe(obj)
    return obj
  }

Vue.options创建以及设置

创建options空对象以及components,filters,directives空对象,设置options._base为Vue,同时将内置组件(KeepAlive)赋值给components

  import builtInComponents from '../components/index'
  Vue.options = Object.create(null)
  ASSET_TYPES.forEach(type => {
    Vue.options[type + 's'] = Object.create(null)
  })

  // this is used to identify the "base" constructor to extend all plain-object
  // components with in Weex's multi-instance scenarios.
  Vue.options._base = Vue
  extend(Vue.options.components, builtInComponents)

挂载 Vue.use

Vue.use是来管理插件的。安装后的插件是放在_installedPlugins数组中。如果插件plugin实现了install函数,则调用install来安装插件。
如果插件plugin本身是函数,则直接调用
因为Vue.use的第一个参数是插件,后面参数是其它可选参数,在处理参数时,会调整参数,将除去第一个参数后的参数作为新的参数列表,同时将Vue作为第一个参数插入到这个新的参数列表中

  initUse(Vue)
  //下面代码在src/core/global-api/use.ts文件中
  export function initUse(Vue: GlobalAPI) {
  Vue.use = function (plugin: Function | any) {
    const installedPlugins =
      this._installedPlugins || (this._installedPlugins = [])
    if (installedPlugins.indexOf(plugin) > -1) {
      return this
    }

    // additional parameters
    const args = toArray(arguments, 1)
    args.unshift(this)
    if (isFunction(plugin.install)) {
      plugin.install.apply(plugin, args)
    } else if (isFunction(plugin)) {
      plugin.apply(null, args)
    }
    installedPlugins.push(plugin)
    return this
  }
}

挂载Vue.mixin

Vue.mixin用于合并options

initMixin(Vue)
//下面代码在src/core/global-api/mixin.ts文件中
export function initMixin(Vue: GlobalAPI) {
  Vue.mixin = function (mixin: Object) {
    this.options = mergeOptions(this.options, mixin)
    return this
  }
}

mergeOptions主要将child.options中的props,inject,directives规范化,同时合并options下的extends和mixins,根据config下的optionMergeStrategies选项合并策略对key作合并处理。
默认的合并策略是在child没有的情况下, 才使用parent选项。

const strats = config.optionMergeStrategies
export function mergeOptions(
  parent: Record<string, any>,
  child: Record<string, any>,
  vm?: Component | null
): ComponentOptions {
  if (isFunction(child)) {
    // @ts-expect-error
    child = child.options
  }

  normalizeProps(child, vm)
  normalizeInject(child, vm)
  normalizeDirectives(child)

  // Apply extends and mixins on the child options,
  // but only if it is a raw options object that isn't
  // the result of another mergeOptions call.
  // Only merged options has the _base property.
  if (!child._base) {
    if (child.extends) {
      parent = mergeOptions(parent, child.extends, vm)
    }
    if (child.mixins) {
      for (let i = 0, l = child.mixins.length; i < l; i++) {
        parent = mergeOptions(parent, child.mixins[i], vm)
      }
    }
  }

  const options: ComponentOptions = {} as any
  let key
  for (key in parent) {
    mergeField(key)
  }
  for (key in child) {
    if (!hasOwn(parent, key)) {
      mergeField(key)
    }
  }
  function mergeField(key: any) {
    const strat = strats[key] || defaultStrat
    options[key] = strat(parent[key], child[key], vm, key)
  }
  return options
}
//默认合并策略
const defaultStrat = function (parentVal: any, childVal: any): any {
  return childVal === undefined ? parentVal : childVal
}

挂载Vue.extend

Vue.extend是通过寄生式组合继承来实现继承
首先看extendOptions._Ctor缓存中是否有父类id对应的继承类,有则使用
使用寄生式组合继承创建子类后,合并options,同时设置子类的父类
初始化子类的options下的props和computed属性
将父类的extend,mixin,use.component, filter,directive赋值给子类
如果有设置组件名,在子类的options.components设置自身
将父类的options赋值给子类的superOptions,继承属性extendOptions赋值给子类的extendOptions,子类之前的选项options赋值给sealedOptions
通过父类id将子类放入缓存

  initExtend(Vue)
  //下面代码在src/core/global-api/extend.ts文件中
  Vue.extend = function (extendOptions: any): typeof Component {
    extendOptions = extendOptions || {}
    const Super = this
    const SuperId = Super.cid
    const cachedCtors = extendOptions._Ctor || (extendOptions._Ctor = {})
    if (cachedCtors[SuperId]) {
      return cachedCtors[SuperId]
    }

    const name =
      getComponentName(extendOptions) || getComponentName(Super.options)

    const Sub = function VueComponent(this: any, options: any) {
      this._init(options)
    } as unknown as typeof Component
    Sub.prototype = Object.create(Super.prototype)
    Sub.prototype.constructor = Sub
    Sub.cid = cid++
    Sub.options = mergeOptions(Super.options, extendOptions)
    Sub['super'] = Super

    // For props and computed properties, we define the proxy getters on
    // the Vue instances at extension time, on the extended prototype. This
    // avoids Object.defineProperty calls for each instance created.
    if (Sub.options.props) {
      initProps(Sub)
    }
    if (Sub.options.computed) {
      initComputed(Sub)
    }

    // allow further extension/mixin/plugin usage
    Sub.extend = Super.extend
    Sub.mixin = Super.mixin
    Sub.use = Super.use

    // create asset registers, so extended classes
    // can have their private assets too.
    ASSET_TYPES.forEach(function (type) {
      Sub[type] = Super[type]
    })
    // enable recursive self-lookup
    if (name) {
      Sub.options.components[name] = Sub
    }

    // keep a reference to the super options at extension time.
    // later at instantiation we can check if Super's options have
    // been updated.
    Sub.superOptions = Super.options
    Sub.extendOptions = extendOptions
    Sub.sealedOptions = extend({}, Sub.options)

    // cache constructor
    cachedCtors[SuperId] = Sub
    return Sub
  }
}

挂载Vue.component,Vue.filter,Vue.directive

主要是自定义组件,过滤器以及指令
如果只是传参id,不传definition,则是直接读取options下的components,filters,directives下id所对应的自定义实现
对于组件类型,并且definition是纯对象时,如果definition有属性name,则使用definition的属性name,否则用id作为definition的name,然后调用Vue.extend来继承definition
对于指令类型,并且definition是函数时,则将bind和update赋值为definition,并且以此作为对象赋值给definition
最后将id与definition的对应关系添加到options.components或者filters或者directives中

  initAssetRegisters(Vue)
  //下面代码在src/core/global-api/assets.ts文件中
export function initAssetRegisters(Vue: GlobalAPI) {
  /**
   * Create asset registration methods.
   */
  ASSET_TYPES.forEach(type => {
    // @ts-expect-error function is not exact same type
    Vue[type] = function (
      id: string,
      definition?: Function | Object
    ): Function | Object | void {
      if (!definition) {
        return this.options[type + 's'][id]
      } else {
        /* istanbul ignore if */
        if (__DEV__ && type === 'component') {
          validateComponentName(id)
        }
        if (type === 'component' && isPlainObject(definition)) {
          // @ts-expect-error
          definition.name = definition.name || id
          definition = this.options._base.extend(definition)
        }
        if (type === 'directive' && isFunction(definition)) {
          definition = { bind: definition, update: definition }
        }
        this.options[type + 's'][id] = definition
        return definition
      }
    }
  })
}

构造函数

Vue构造函数定义在src/core/instance/index.ts文件中,构造函数中会调用原型方法init

function Vue(options) {
  this._init(options)
}

initMixin

定义原型_init方法,在src/core/instance/init.ts文件中

export function initMixin(Vue: typeof Component) {
	Vue.prototype._init = function (options?: Record<string, any>) {
		....
	}
}

设置基础属性

设置_uid

每个vue实例都有一个_uid来作唯一标识,其值从0开始累加

let uid = 0
vm._uid = uid++
设置_isVue

用于标识实体是vue

vm._isVue = true
设置__v_skip

在作响应式处理时,忽略vue实例

vm.__v_skip = true
设置_scope

设置副作用域,兼容vue3

vm._scope = new EffectScope(true /* detached */)
vm._scope._vm = true
设置 $options

合并创建vue. o p t i o n s 如果 o p t o i n s 包 含 i s C o m p o n e n t , 则调用 i n i t I n t e r n a l C o m p o n e n t 指定组件 options 如果optoins包含_isComponent,则调用initInternalComponent指定组件 options如果optoinsisComponent,则调用initInternalComponent指定组件options原型,同时将options中的_parentVnode和parent赋值给$options,以及依赖父节点组件选项中的propsData,listeners,children和tag分别赋给 $options的propsData,_parentListeners,_renderChildren和_componentTag,如果options下包含render,把render和staticRenderFns赋值给$options的render和staticRenderFns
否则就解析父类的选项,看是否有修改,如果有修改,则以修改后的选项再作一次合并

   if (options && options._isComponent) {
      // optimize internal component instantiation
      // since dynamic options merging is pretty slow, and none of the
      // internal component options needs special treatment.
      initInternalComponent(vm, options as any)
    } else {
      vm.$options = mergeOptions(
        resolveConstructorOptions(vm.constructor as any),
        options || {},
        vm
      )
    }

export function initInternalComponent(
  vm: Component,
  options: InternalComponentOptions
) {
  const opts = (vm.$options = Object.create((vm.constructor as any).options))
  // doing this because it's faster than dynamic enumeration.
  const parentVnode = options._parentVnode
  opts.parent = options.parent
  opts._parentVnode = parentVnode

  const vnodeComponentOptions = parentVnode.componentOptions!
  opts.propsData = vnodeComponentOptions.propsData
  opts._parentListeners = vnodeComponentOptions.listeners
  opts._renderChildren = vnodeComponentOptions.children
  opts._componentTag = vnodeComponentOptions.tag

  if (options.render) {
    opts.render = options.render
    opts.staticRenderFns = options.staticRenderFns
  }
}

export function resolveConstructorOptions(Ctor: typeof Component) {
  let options = Ctor.options
  if (Ctor.super) {
    const superOptions = resolveConstructorOptions(Ctor.super)
    const cachedSuperOptions = Ctor.superOptions
    if (superOptions !== cachedSuperOptions) {
      // super option changed,
      // need to resolve new options.
      Ctor.superOptions = superOptions
      // check if there are any late-modified/attached options (#4976)
      const modifiedOptions = resolveModifiedOptions(Ctor)
      // update base extend options
      if (modifiedOptions) {
        extend(Ctor.extendOptions, modifiedOptions)
      }
      options = Ctor.options = mergeOptions(superOptions, Ctor.extendOptions)
      if (options.name) {
        options.components[options.name] = Ctor
      }
    }
  }
  return options
}
设置_self

对外暴露自己

 vm._self = vm

初始化生命周期相关的属性

设置属性有$parent,$root,$children,$refs, _provided ,_watcher,_inactive,_direcInactive,_isMounted,_isDestroyed和_isBeingDestroyed
同时会查找当前vue实例的第一个非抽象父类,将其放入其$children中

export function initLifecycle(vm: Component) {
  const options = vm.$options

  // locate first non-abstract parent
  let parent = options.parent
  if (parent && !options.abstract) {
    while (parent.$options.abstract && parent.$parent) {
      parent = parent.$parent
    }
    parent.$children.push(vm)
  }

  vm.$parent = parent
  vm.$root = parent ? parent.$root : vm

  vm.$children = []
  vm.$refs = {}

  vm._provided = parent ? parent._provided : Object.create(null)
  vm._watcher = null
  vm._inactive = null
  vm._directInactive = false
  vm._isMounted = false
  vm._isDestroyed = false
  vm._isBeingDestroyed = false
}

初始化事件相关

设置实例中的_events,_hasHookEvent以及$options._parentListeners

export function initEvents(vm: Component) {
  vm._events = Object.create(null)
  vm._hasHookEvent = false
  // init parent attached events
  const listeners = vm.$options._parentListeners
  if (listeners) {
    updateComponentListeners(vm, listeners)
  }
}

updateComponentListeners在更新组件的事件监听器时,会根据遍历新的事件监听器属性,比较前后两次事件监听器对应属性的值情况,如果老的属性没有定义,而新的有定义,但是子属性fns没有定义,则创建,并且调用add添加到$on回调中,如果新的和旧的监听器对应的属性不相等,则使用新的监听器中的属性,同时对于旧事件监听器中不存在于新事件监听器的则删除

export function updateComponentListeners(
  vm: Component,
  listeners: Object,
  oldListeners?: Object | null
) {
  target = vm
  updateListeners(
    listeners,
    oldListeners || {},
    add,
    remove,
    createOnceHandler,
    vm
  )
  target = undefined
}

export function updateListeners(
  on: Object,
  oldOn: Object,
  add: Function,
  remove: Function,
  createOnceHandler: Function,
  vm: Component
) {
  let name, cur, old, event
  for (name in on) {
    cur = on[name]
    old = oldOn[name]
    event = normalizeEvent(name)
    if (isUndef(cur)) {
      __DEV__ &&
        warn(
          `Invalid handler for event "${event.name}": got ` + String(cur),
          vm
        )
    } else if (isUndef(old)) {
      if (isUndef(cur.fns)) {
        cur = on[name] = createFnInvoker(cur, vm)
      }
      if (isTrue(event.once)) {
        cur = on[name] = createOnceHandler(event.name, cur, event.capture)
      }
      add(event.name, cur, event.capture, event.passive, event.params)
    } else if (cur !== old) {
      old.fns = cur
      on[name] = old
    }
  }
  for (name in oldOn) {
    if (isUndef(on[name])) {
      event = normalizeEvent(name)
      remove(event.name, oldOn[name], event.capture)
    }
  }
}

function add(event, fn) {
  target.$on(event, fn)
}

function remove(event, fn) {
  target.$off(event, fn)
}

function createOnceHandler(event, fn) {
  const _target = target
  return function onceHandler() {
    const res = fn.apply(null, arguments)
    if (res !== null) {
      _target.$off(event, onceHandler)
    }
  }
}

初始化渲染相关

设置_vnode, _staticTrees, $vnode, $slots, $scopedSlots,_c, $createElement
将$attrs和$listeners设置为响应式的

export function initRender(vm: Component) {
  vm._vnode = null // the root of the child tree
  vm._staticTrees = null // v-once cached trees
  const options = vm.$options
  const parentVnode = (vm.$vnode = options._parentVnode!) // the placeholder node in parent tree
  const renderContext = parentVnode && (parentVnode.context as Component)
  vm.$slots = resolveSlots(options._renderChildren, renderContext)
  vm.$scopedSlots = parentVnode
    ? normalizeScopedSlots(
        vm.$parent!,
        parentVnode.data!.scopedSlots,
        vm.$slots
      )
    : emptyObject
  // bind the createElement fn to this instance
  // so that we get proper render context inside it.
  // args order: tag, data, children, normalizationType, alwaysNormalize
  // internal version is used by render functions compiled from templates
  // @ts-expect-error
  vm._c = (a, b, c, d) => createElement(vm, a, b, c, d, false)
  // normalization is always applied for the public version, used in
  // user-written render functions.
  // @ts-expect-error
  vm.$createElement = (a, b, c, d) => createElement(vm, a, b, c, d, true)

  // $attrs & $listeners are exposed for easier HOC creation.
  // they need to be reactive so that HOCs using them are always updated
  const parentData = parentVnode && parentVnode.data

  /* istanbul ignore else */
	defineReactive(
	  vm,
	  '$attrs',
	  (parentData && parentData.attrs) || emptyObject,
	  null,
	  true
	)
	defineReactive(
	  vm,
	  '$listeners',
	  options._parentListeners || emptyObject,
	  null,
	  true
	)
}

调用beforeCreate钩子

在调用钩子时,会禁止响应数据收集,是通过将null加入到栈中
实例中如何设置有beforeCreate属性,则调用回调,同时如果有钩子事件,则触发事件
最后就是恢复环境

callHook(vm, 'beforeCreate', undefined, false /* setContext */)

export function callHook(
  vm: Component,
  hook: string,
  args?: any[],
  setContext = true
) {
  // #7573 disable dep collection when invoking lifecycle hooks
  pushTarget()
  const prev = currentInstance
  setContext && setCurrentInstance(vm)
  const handlers = vm.$options[hook]
  const info = `${hook} hook`
  if (handlers) {
    for (let i = 0, j = handlers.length; i < j; i++) {
      invokeWithErrorHandling(handlers[i], vm, args || null, vm, info)
    }
  }
  if (vm._hasHookEvent) {
    vm.$emit('hook:' + hook)
  }
  setContext && setCurrentInstance(prev)
  popTarget()
}

初始化injection

解析$options中的inject,,遍历inject对象中的属性,不处理__ob__,在属性对应的值为对象时,包含from和default默认值,在有from属性时,从_provied获取对应的值作为属性对应的值,否则如果default对应的值是函数,则将函数调用后的值作为属性对应的值同,否则将default对应的值作为属性对应的值。
遍历result,将vue实例对应的key设置为响应式的

export function initInjections(vm: Component) {
  const result = resolveInject(vm.$options.inject, vm)
  if (result) {
    toggleObserving(false)
    Object.keys(result).forEach(key => {
      /* istanbul ignore else */
        defineReactive(vm, key, result[key])
    })
    toggleObserving(true)
  }
}

export function resolveInject(
  inject: any,
  vm: Component
): Record<string, any> | undefined | null {
  if (inject) {
    // inject is :any because flow is not smart enough to figure out cached
    const result = Object.create(null)
    const keys = hasSymbol ? Reflect.ownKeys(inject) : Object.keys(inject)

    for (let i = 0; i < keys.length; i++) {
      const key = keys[i]
      // #6574 in case the inject object is observed...
      if (key === '__ob__') continue
      const provideKey = inject[key].from
      if (provideKey in vm._provided) {
        result[key] = vm._provided[provideKey]
      } else if ('default' in inject[key]) {
        const provideDefault = inject[key].default
        result[key] = isFunction(provideDefault)
          ? provideDefault.call(vm)
          : provideDefault
      } else if (__DEV__) {
        warn(`Injection "${key as string}" not found`, vm)
      }
    }
    return result
  }
}

初始化state

  • 初始化props
 if (opts.props) initProps(vm, opts.props)
 function initProps(vm: Component, propsOptions: Object) {
  const propsData = vm.$options.propsData || {}
  const props = (vm._props = shallowReactive({}))
  // cache prop keys so that future props updates can iterate using Array
  // instead of dynamic object key enumeration.
  const keys: string[] = (vm.$options._propKeys = [])
  const isRoot = !vm.$parent
  // root instance props should be converted
  if (!isRoot) {
    toggleObserving(false)
  }
  for (const key in propsOptions) {
    keys.push(key)
    const value = validateProp(key, propsOptions, propsData, vm)
    /* istanbul ignore else */
    
    defineReactive(props, key, value)
    
    // static props are already proxied on the component's prototype
    // during Vue.extend(). We only need to proxy props defined at
    // instantiation here.
    if (!(key in vm)) {
      proxy(vm, `_props`, key)
    }
  }
  toggleObserving(true)
}
  • 初始化setup
export function initSetup(vm: Component) {
  const options = vm.$options
  const setup = options.setup
  if (setup) {
    const ctx = (vm._setupContext = createSetupContext(vm))

    setCurrentInstance(vm)
    pushTarget()
    const setupResult = invokeWithErrorHandling(
      setup,
      null,
      [vm._props || shallowReactive({}), ctx],
      vm,
      `setup`
    )
    popTarget()
    setCurrentInstance()

    if (isFunction(setupResult)) {
      // render function
      // @ts-ignore
      options.render = setupResult
    } else if (isObject(setupResult)) {
      // bindings
      vm._setupState = setupResult
      // __sfc indicates compiled bindings from <script setup>
      if (!setupResult.__sfc) {
        for (const key in setupResult) {
          if (!isReserved(key)) {
            proxyWithRefUnwrap(vm, setupResult, key)
          }
        }
      } else {
        // exposed for compiled render fn
        const proxy = (vm._setupProxy = {})
        for (const key in setupResult) {
          if (key !== '__sfc') {
            proxyWithRefUnwrap(proxy, setupResult, key)
          }
        }
      }
    }
  }
}
  • 初始化methods
if (opts.methods) initMethods(vm, opts.methods)

function initMethods(vm: Component, methods: Object) {
  for (const key in methods) {
    vm[key] = typeof methods[key] !== 'function' ? noop : bind(methods[key], vm)
  }
}
  • 初始化data
  if (opts.data) {
    initData(vm)
  } else {
    const ob = observe((vm._data = {}))
    ob && ob.vmCount++
  }
function initData(vm: Component) {
  let data: any = vm.$options.data
  data = vm._data = isFunction(data) ? getData(data, vm) : data || {}
  if (!isPlainObject(data)) {
    data = {}
  }
  // proxy data on instance
  const keys = Object.keys(data)
  const props = vm.$options.props
  const methods = vm.$options.methods
  let i = keys.length
  while (i--) {
    const key = keys[i]
    if (props && hasOwn(props, key)) {
   
    } else if (!isReserved(key)) {
      proxy(vm, `_data`, key)
    }
  }
  // observe data
  const ob = observe(data)
  ob && ob.vmCount++
}

export function getData(data: Function, vm: Component): any {
  // #7573 disable dep collection when invoking data getters
  pushTarget()
  try {
    return data.call(vm, vm)
  } catch (e: any) {
    handleError(e, vm, `data()`)
    return {}
  } finally {
    popTarget()
  }
}
  • 初始化computed
if (opts.computed) initComputed(vm, opts.computed)

function initComputed(vm: Component, computed: Object) {
  // $flow-disable-line
  const watchers = (vm._computedWatchers = Object.create(null))
  // computed properties are just getters during SSR
  const isSSR = isServerRendering()

  for (const key in computed) {
    const userDef = computed[key]
    const getter = isFunction(userDef) ? userDef : userDef.get

    if (!isSSR) {
      // create internal watcher for the computed property.
      watchers[key] = new Watcher(
        vm,
        getter || noop,
        noop,
        computedWatcherOptions
      )
    }

    // component-defined computed properties are already defined on the
    // component prototype. We only need to define computed properties defined
    // at instantiation here.
    if (!(key in vm)) {
      defineComputed(vm, key, userDef)
    }
  }
}
  • 初始化watcher
  if (opts.watch && opts.watch !== nativeWatch) {
    initWatch(vm, opts.watch)
  }

function initWatch(vm: Component, watch: Object) {
  for (const key in watch) {
    const handler = watch[key]
    if (isArray(handler)) {
      for (let i = 0; i < handler.length; i++) {
        createWatcher(vm, key, handler[i])
      }
    } else {
      createWatcher(vm, key, handler)
    }
  }
}

function createWatcher(
  vm: Component,
  expOrFn: string | (() => any),
  handler: any,
  options?: Object
) {
  if (isPlainObject(handler)) {
    options = handler
    handler = handler.handler
  }
  if (typeof handler === 'string') {
    handler = vm[handler]
  }
  return vm.$watch(expOrFn, handler, options)
}

初始化provide

将$options下的provide添加到vm._provide文章来源地址https://www.toymoban.com/news/detail-421296.html

export function initProvide(vm: Component) {
  const provideOption = vm.$options.provide
  if (provideOption) {
    const provided = isFunction(provideOption)
      ? provideOption.call(vm)
      : provideOption
    if (!isObject(provided)) {
      return
    }
    const source = resolveProvided(vm)
    // IE9 doesn't support Object.getOwnPropertyDescriptors so we have to
    // iterate the keys ourselves.
    const keys = hasSymbol ? Reflect.ownKeys(provided) : Object.keys(provided)
    for (let i = 0; i < keys.length; i++) {
      const key = keys[i]
      Object.defineProperty(
        source,
        key,
        Object.getOwnPropertyDescriptor(provided, key)!
      )
    }
  }
}

调用created钩子

    callHook(vm, 'created')

挂载

    if (vm.$options.el) {
      vm.$mount(vm.$options.el)
    }

到了这里,关于vue中初始化的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【PostgreSQL】Ubuntu 下使用 Prisma 的初始化流程

    步骤如下: 创建 Ubuntu 用户 创建 PostgreSQL 用户 使用 postgres 用户登录,然后创建新用户: 设置用户密码 使用 postgres 或 projectname 用户登录,设置用户密码: 完成上面准备工作就ok了,不需要手工创建数据库,因为下面将由 Prisma 来创建数据库。 Prisma 初始化 schema.prisma 创建好

    2024年01月18日
    浏览(67)
  • Spring 填充属性和初始化流程源码剖析及扩展实现

    在上一篇博文 讲解 Spring 实例化的不同方式及相关生命周期源码剖析 介绍了 Spring 实例化的不同方式,本文主要围绕实例化过后对象的填充属性和初始化过程进行详细流程剖析 回顾前言知识,doCreateBean-createBeanInstance,通过 Supplier 接口、FactoryMethod、构造函数反射 invoke,创建

    2024年02月06日
    浏览(44)
  • 从内核源码看 slab 内存池的创建初始化流程

    在上篇文章 《细节拉满,80 张图带你一步一步推演 slab 内存池的设计与实现 》中,笔者从 slab cache 的总体架构演进角度以及 slab cache 的运行原理角度为大家勾勒出了 slab cache 的总体架构视图,基于这个视图详细阐述了 slab cache 的内存分配以及释放原理。 slab cache 机制确实比

    2023年04月12日
    浏览(56)
  • ORB_SLAM3:单目+IMU初始化流程梳理

    单目+IMU模式下,前面的一些配置完成后,处理第一帧图像时: 1、每帧图像都会调用该函数: 目的:使灰度直方图分布较为均匀,从而使整体对比度更强,便于后面特征点的提取等工作; 2、第一帧图像(ni=0)时无IMU数据(vImuMeas容器为空),进入下面的这个函数: 该函数先

    2024年02月10日
    浏览(44)
  • vue中初始化

    主要是挂载一些全局方法 响应数据相关的Vue.set, Vue.delete, Vue.nextTick以及Vue.observable 插件相关的Vue.use 对象合并相关Vue.mixin 类继承相关的Vue.extend 资源相关,如组件,过滤器,自定义指令Vue.component, Vue.filter, Vue.directive 配置相关Vue.config以及Vue.options中的components,filters,directives 定

    2023年04月22日
    浏览(48)
  • vhost-net-原理-初始化流程-数据传输流程-vhost-net后端

    传统的virtio网卡是通过虚拟机内部的virtio驱动作为前端,负责将虚拟机内部的IO请求封装到vring descriptor中,然后通过写MMIO或PIO的方式通知QEMU中的virtio后端设备,QEMU将这些IO请求设备发送到tap设备,然后通过网桥发送到真实的网卡上 vhost方案也是通过虚拟机中的virtio驱动将I

    2024年02月11日
    浏览(41)
  • Vue初始化项目加载逻辑

    项目创建 我们只需要创建项目即可,剩余的依赖都没必要安装 我们先来看main.js,咱们加了一行备注 通过备注可知,我们首先加载的是App.vue 我们再来看一下App.vue 里都有啥 也就是下面这个红框里的内容才是 那下面的内容是哪里来的呢 那就需要看一下路由设置了 我们看到/目

    2024年02月08日
    浏览(104)
  • Orangepi Zero2 全志H616(一):配置初始化和启动流程

    目录 一,Orangepi简单说明 ①为什么使用全志H616 ②基本特性 ③配套操作系统支持 二,刷机和系统启动 ①准备工具 ②登录系统 ● 开发板供电 ● 登录 ● 开发板上板载LED灯测试说明 ③修改登录密码 ④网络配置 ⑤SSH登陆开发板 三,vim设置:tab键缩进及代码行数显示 四,全志

    2024年02月04日
    浏览(49)
  • android存储3--初始化.unlock事件的处理

    android版本:android-11.0.0_r21 http://aospxref.com/android-11.0.0_r21 概述:SystemServiceManager收到unlock事件后,遍历service链表,执行各个service的onUserUnlocking。对于存储service,执行的是StorageManagerService$Lifecycle中的 onUserUnlocking,在这个方法中,存储的 StorageSessionController、vold、storaged模块进行

    2024年02月10日
    浏览(52)
  • Kafka3.0.0版本——消费者(消费者组初始化流程图解)

    每个consumer都发送JoinGroup请求,如下图所示: 选出一个consumer作为leader,如下图所示: 把要消费的topic情况发送给leader 消费者,如下图所示: leader会负责制定消费方案,并把消费方案发给coordinator,如下图所示: Coordinator就把消费方案下发给各个consumer,如下图所示: 每个消

    2024年02月09日
    浏览(37)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包