国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

vue中初始化

這篇具有很好參考價值的文章主要介紹了vue中初始化。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

初始化流程

initGlobalAPI處理流程

主要是掛載一些全局方法

  • 響應(yīng)數(shù)據(jù)相關(guān)的Vue.set, Vue.delete, Vue.nextTick以及Vue.observable
  • 插件相關(guān)的Vue.use
  • 對象合并相關(guān)Vue.mixin
  • 類繼承相關(guān)的Vue.extend
  • 資源相關(guān),如組件,過濾器,自定義指令Vue.component, Vue.filter, Vue.directive
  • 配置相關(guān)Vue.config以及Vue.options中的components,filters,directives

定義屬性config

給Vue對象添加config屬性,其中config是在src/core/config.ts文件中導(dǎo)出的

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
  }

掛載響應(yīng)式相關(guān)方法

設(shè)置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創(chuàng)建以及設(shè)置

創(chuàng)建options空對象以及components,filters,directives空對象,設(shè)置options._base為Vue,同時將內(nèi)置組件(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數(shù)組中。如果插件plugin實現(xiàn)了install函數(shù),則調(diào)用install來安裝插件。
如果插件plugin本身是函數(shù),則直接調(diào)用
因為Vue.use的第一個參數(shù)是插件,后面參數(shù)是其它可選參數(shù),在處理參數(shù)時,會調(diào)整參數(shù),將除去第一個參數(shù)后的參數(shù)作為新的參數(shù)列表,同時將Vue作為第一個參數(shù)插入到這個新的參數(shù)列表中

  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規(guī)范化,同時合并options下的extends和mixins,根據(jù)config下的optionMergeStrategies選項合并策略對key作合并處理。
默認(rèn)的合并策略是在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
}
//默認(rèn)合并策略
const defaultStrat = function (parentVal: any, childVal: any): any {
  return childVal === undefined ? parentVal : childVal
}

掛載Vue.extend

Vue.extend是通過寄生式組合繼承來實現(xiàn)繼承
首先看extendOptions._Ctor緩存中是否有父類id對應(yīng)的繼承類,有則使用
使用寄生式組合繼承創(chuàng)建子類后,合并options,同時設(shè)置子類的父類
初始化子類的options下的props和computed屬性
將父類的extend,mixin,use.component, filter,directive賦值給子類
如果有設(shè)置組件名,在子類的options.components設(shè)置自身
將父類的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所對應(yīng)的自定義實現(xiàn)
對于組件類型,并且definition是純對象時,如果definition有屬性name,則使用definition的屬性name,否則用id作為definition的name,然后調(diào)用Vue.extend來繼承definition
對于指令類型,并且definition是函數(shù)時,則將bind和update賦值為definition,并且以此作為對象賦值給definition
最后將id與definition的對應(yīng)關(guān)系添加到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
      }
    }
  })
}

構(gòu)造函數(shù)

Vue構(gòu)造函數(shù)定義在src/core/instance/index.ts文件中,構(gòu)造函數(shù)中會調(diào)用原型方法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>) {
		....
	}
}

設(shè)置基礎(chǔ)屬性

設(shè)置_uid

每個vue實例都有一個_uid來作唯一標(biāo)識,其值從0開始累加

let uid = 0
vm._uid = uid++
設(shè)置_isVue

用于標(biāo)識實體是vue

vm._isVue = true
設(shè)置__v_skip

在作響應(yīng)式處理時,忽略vue實例

vm.__v_skip = true
設(shè)置_scope

設(shè)置副作用域,兼容vue3

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

合并創(chuàng)建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 , 則調(diào)用 i n i t I n t e r n a l C o m p o n e n t 指定組件 options 如果optoins包含_isComponent,則調(diào)用initInternalComponent指定組件 options如果optoinsi?sComponent,則調(diào)用initInternalComponent指定組件options原型,同時將options中的_parentVnode和parent賦值給$options,以及依賴父節(jié)點組件選項中的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
}
設(shè)置_self

對外暴露自己

 vm._self = vm

初始化生命周期相關(guān)的屬性

設(shè)置屬性有$parent,$root,$children,$refs, _provided ,_watcher,_inactive,_direcInactive,_isMounted,_isDestroyed和_isBeingDestroyed
同時會查找當(dāng)前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
}

初始化事件相關(guān)

設(shè)置實例中的_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在更新組件的事件監(jiān)聽器時,會根據(jù)遍歷新的事件監(jiān)聽器屬性,比較前后兩次事件監(jiān)聽器對應(yīng)屬性的值情況,如果老的屬性沒有定義,而新的有定義,但是子屬性fns沒有定義,則創(chuàng)建,并且調(diào)用add添加到$on回調(diào)中,如果新的和舊的監(jiān)聽器對應(yīng)的屬性不相等,則使用新的監(jiān)聽器中的屬性,同時對于舊事件監(jiān)聽器中不存在于新事件監(jiān)聽器的則刪除

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)
    }
  }
}

初始化渲染相關(guān)

設(shè)置_vnode, _staticTrees, $vnode, $slots, $scopedSlots,_c, $createElement
將$attrs和$listeners設(shè)置為響應(yīng)式的

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
	)
}

調(diào)用beforeCreate鉤子

在調(diào)用鉤子時,會禁止響應(yīng)數(shù)據(jù)收集,是通過將null加入到棧中
實例中如何設(shè)置有beforeCreate屬性,則調(diào)用回調(diào),同時如果有鉤子事件,則觸發(fā)事件
最后就是恢復(fù)環(huán)境

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__,在屬性對應(yīng)的值為對象時,包含from和default默認(rèn)值,在有from屬性時,從_provied獲取對應(yīng)的值作為屬性對應(yīng)的值,否則如果default對應(yīng)的值是函數(shù),則將函數(shù)調(diào)用后的值作為屬性對應(yīng)的值同,否則將default對應(yīng)的值作為屬性對應(yīng)的值。
遍歷result,將vue實例對應(yīng)的key設(shè)置為響應(yīng)式的

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文章來源地址http://www.zghlxwxcb.cn/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)!
      )
    }
  }
}

調(diào)用created鉤子

    callHook(vm, 'created')

掛載

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

到了這里,關(guān)于vue中初始化的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進(jìn)行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

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

    步驟如下: 創(chuàng)建 Ubuntu 用戶 創(chuàng)建 PostgreSQL 用戶 使用 postgres 用戶登錄,然后創(chuàng)建新用戶: 設(shè)置用戶密碼 使用 postgres 或 projectname 用戶登錄,設(shè)置用戶密碼: 完成上面準(zhǔn)備工作就ok了,不需要手工創(chuàng)建數(shù)據(jù)庫,因為下面將由 Prisma 來創(chuàng)建數(shù)據(jù)庫。 Prisma 初始化 schema.prisma 創(chuàng)建好

    2024年01月18日
    瀏覽(27)
  • Spring 填充屬性和初始化流程源碼剖析及擴(kuò)展實現(xiàn)

    Spring 填充屬性和初始化流程源碼剖析及擴(kuò)展實現(xiàn)

    在上一篇博文 講解 Spring 實例化的不同方式及相關(guān)生命周期源碼剖析 介紹了 Spring 實例化的不同方式,本文主要圍繞實例化過后對象的填充屬性和初始化過程進(jìn)行詳細(xì)流程剖析 回顧前言知識,doCreateBean-createBeanInstance,通過 Supplier 接口、FactoryMethod、構(gòu)造函數(shù)反射 invoke,創(chuàng)建

    2024年02月06日
    瀏覽(28)
  • 從內(nèi)核源碼看 slab 內(nèi)存池的創(chuàng)建初始化流程

    從內(nèi)核源碼看 slab 內(nèi)存池的創(chuàng)建初始化流程

    在上篇文章 《細(xì)節(jié)拉滿,80 張圖帶你一步一步推演 slab 內(nèi)存池的設(shè)計與實現(xiàn) 》中,筆者從 slab cache 的總體架構(gòu)演進(jìn)角度以及 slab cache 的運(yùn)行原理角度為大家勾勒出了 slab cache 的總體架構(gòu)視圖,基于這個視圖詳細(xì)闡述了 slab cache 的內(nèi)存分配以及釋放原理。 slab cache 機(jī)制確實比

    2023年04月12日
    瀏覽(100)
  • ORB_SLAM3:單目+IMU初始化流程梳理

    單目+IMU模式下,前面的一些配置完成后,處理第一幀圖像時: 1、每幀圖像都會調(diào)用該函數(shù): 目的:使灰度直方圖分布較為均勻,從而使整體對比度更強(qiáng),便于后面特征點的提取等工作; 2、第一幀圖像(ni=0)時無IMU數(shù)據(jù)(vImuMeas容器為空),進(jìn)入下面的這個函數(shù): 該函數(shù)先

    2024年02月10日
    瀏覽(23)
  • vue中初始化

    主要是掛載一些全局方法 響應(yīng)數(shù)據(jù)相關(guān)的Vue.set, Vue.delete, Vue.nextTick以及Vue.observable 插件相關(guān)的Vue.use 對象合并相關(guān)Vue.mixin 類繼承相關(guān)的Vue.extend 資源相關(guān),如組件,過濾器,自定義指令Vue.component, Vue.filter, Vue.directive 配置相關(guān)Vue.config以及Vue.options中的components,filters,directives 定

    2023年04月22日
    瀏覽(37)
  • vhost-net-原理-初始化流程-數(shù)據(jù)傳輸流程-vhost-net后端

    vhost-net-原理-初始化流程-數(shù)據(jù)傳輸流程-vhost-net后端

    傳統(tǒng)的virtio網(wǎng)卡是通過虛擬機(jī)內(nèi)部的virtio驅(qū)動作為前端,負(fù)責(zé)將虛擬機(jī)內(nèi)部的IO請求封裝到vring descriptor中,然后通過寫MMIO或PIO的方式通知QEMU中的virtio后端設(shè)備,QEMU將這些IO請求設(shè)備發(fā)送到tap設(shè)備,然后通過網(wǎng)橋發(fā)送到真實的網(wǎng)卡上 vhost方案也是通過虛擬機(jī)中的virtio驅(qū)動將I

    2024年02月11日
    瀏覽(24)
  • Vue初始化項目加載邏輯

    Vue初始化項目加載邏輯

    項目創(chuàng)建 我們只需要創(chuàng)建項目即可,剩余的依賴都沒必要安裝 我們先來看main.js,咱們加了一行備注 通過備注可知,我們首先加載的是App.vue 我們再來看一下App.vue 里都有啥 也就是下面這個紅框里的內(nèi)容才是 那下面的內(nèi)容是哪里來的呢 那就需要看一下路由設(shè)置了 我們看到/目

    2024年02月08日
    瀏覽(24)
  • Orangepi Zero2 全志H616(一):配置初始化和啟動流程

    Orangepi Zero2 全志H616(一):配置初始化和啟動流程

    目錄 一,Orangepi簡單說明 ①為什么使用全志H616 ②基本特性 ③配套操作系統(tǒng)支持 二,刷機(jī)和系統(tǒng)啟動 ①準(zhǔn)備工具 ②登錄系統(tǒng) ● 開發(fā)板供電 ● 登錄 ● 開發(fā)板上板載LED燈測試說明 ③修改登錄密碼 ④網(wǎng)絡(luò)配置 ⑤SSH登陸開發(fā)板 三,vim設(shè)置:tab鍵縮進(jìn)及代碼行數(shù)顯示 四,全志

    2024年02月04日
    瀏覽(26)
  • android存儲3--初始化.unlock事件的處理

    android存儲3--初始化.unlock事件的處理

    android版本:android-11.0.0_r21 http://aospxref.com/android-11.0.0_r21 概述:SystemServiceManager收到unlock事件后,遍歷service鏈表,執(zhí)行各個service的onUserUnlocking。對于存儲service,執(zhí)行的是StorageManagerService$Lifecycle中的 onUserUnlocking,在這個方法中,存儲的 StorageSessionController、vold、storaged模塊進(jìn)行

    2024年02月10日
    瀏覽(42)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包