new Vue 发生了什么

new Vue 发生了什么

1. mergeOptions

合并options

2. initLifecycle(vm)

初始化生命周期

3. initEvents(vm)

初始化事件

4. initRender(vm):初始化render

初始化渲染

5. callHook(vm, 'beforeCreate'):触发 beforeCreate 钩子

触发 beforeCreate 钩子

6. initInjections(vm) // resolve injections before data/props

7. initState(vm):初始化 props、data、computed、methodswatch

export function initState (vm: Component) {
  vm._watchers = []
  const opts = vm.$options
  if (opts.props) initProps(vm, opts.props)
  if (opts.methods) initMethods(vm, opts.methods)
  if (opts.data) {
    initData(vm)
  } else {
    observe(vm._data = {}, true /* asRootData */)
  }
  if (opts.computed) initComputed(vm, opts.computed)
  if (opts.watch && opts.watch !== nativeWatch) {
    initWatch(vm, opts.watch)
  }
}

9. initProvide(vm) // resolve provide after data/props

10. callHook(vm, 'created'):触发 created 钩子

触发 created 钩子


init

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

initMixin(Vue)

function initMixin(Vue) {
  Vue.prototype._init = function(options) {
    const vm = this
    // 一个防止观察自身的标志
    vm._isVue = true
    vm.$options = options
  }

  initState(vm)

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

const inBrowser = typeof window !== 'undefined'
Vue.prototype.$mount = function (el, hydrating) {
  el = el && inBrowser ? query(el) : undefined
  return mountComponent(this, el, hydrating)
}
function mountComponent(vm, el, hydrating) {
  vm.$el = el

  let updateComponent = () => {
    vm._update(vm._render(), hydrating)
  }
}
// 缓存之前的$mount
const mount = Vue.prototype.$mount
Vue.prototype.$mount = function(el, hydrating) {
  el = el && query(el)

  const options = this.$options
  if (!options.render) {
    let template = options.template
    if (template) {
      // .
    } else {
      template = getOuterHTML(el)
    }
  }

  return mount.call(this, el, hydrating)
}

function query (el) {
  if (typeof el === 'string') {
    const selected = document.querySelector(el)
    if (!selected) {
      // process.env.NODE_ENV !== 'production' && warn(
      //   'Cannot find element: ' + el
      // )
      return document.createElement('div')
    }
    return selected
  } else {
    return el
  }
}

function getOuterHTML (el) {
  if (el.outerHTML) {
    return el.outerHTML
  } else {
    const container = document.createElement('div')
    container.appendChild(el.cloneNode(true))
    return container.innerHTML
  }
}

function initState(vm) {
  const opts = vm.$options
  if (opts.data) {
    initData(vm)
  } else {
    observe(vm._data = {}, true)
  }
}

function initData(vm) {
  let data = vm.$options.data
  data = vm._data =  typeof data === 'function'
  ? getData(data, vm)
  : data || {}

  const keys = Object.keys(data)
  let i = keys.length
  while (i--) {
    proxy(vm, `_data`, key)
  }

  observe(data, true /* asRootData */)
}

function getData(data, vm) {
  return data.call(vm, vm)
}

const sharedPropertyDefinition = {
  enumerable: true,
  configurable: true,
  get: noop,
  set: noop
}

// 等待,无操作
function noop() {}

function proxy(target, sourceKey, key) {
  sharedPropertyDefinition.get = function proxyGetter () {
    return this[sourceKey][key]
  }
  sharedPropertyDefinition.set = function proxySetter (val) {
    this[sourceKey][key] = val
  }
  Object.defineProperty(target, key, sharedPropertyDefinition)
}

function observe(value, asRootData) {

}

vdom

js对象描述真实dom

为什么使用vdom

手动操作dom比较麻烦,还要考虑兼容性问题,虽然有jquery等库简化操作,但随着项目增大,复杂度不断提升

为了简化操作dom,可以使用模板引擎,但是模板引擎没有解决跟踪状态变化的问题,于是vdom出现了

  • 开销更小
  • 可以合并更改
  • 可以跟踪上一次的状态,并且用作diff

技巧

将事件的创建和销毁写在一起

Vue 中,可以用$on$once去监听所有的生命周期钩子函数,如监听组件的updated钩子函数可以写成this.$on('hook:updated', () => {})

mounted(){
  window.addEventListener('resize', xxx)
  // 通过hook监听组件销毁钩子函数,并取消监听事件
  this.$once('hook:beforeDestroy', () => {
    window.removeEventListener('resize', xxx)
  })
}

监听子组件的生命周期

需要监听第三方组件数据的变化,但是组件又没有提供change事件

<child @hook:updated="childUpdated" />
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值