首次渲染过程
- 在Vue函数中调用this.init()函数
- F11进入init()函数
- 首先增加一个标记Vue._isvue() = true 如果是vue实例是不需要observed,不进行响应式处理
- 判断当前的vue实例是否是组件、如果是组件的则合并option选项
- 如果传的是实例则将用户传的options和vue构造函数的options进行合并
- 接下来设置renderProxy,渲染时候的代理对象。
- 先判断当前环境是否支持proxy。如果支持则使用proxy
- 如果不支持直接赋值给vm._renderProxy()
- 执行一些init(),给vue挂在实例。
- month进入这个方法,获取当前vue实例上的options
- 判断当前option上是否有render()函数如果有只直接解析render,
- 如果没有的则执行template模板。如果template是是元素则直接返回template.innerHtml
- 如果是字符串的话则判断是否选择器。根据选择器获取元素。然后渲染。
- 判断是否有el
- 如果el存在则执行el.innerhtml()
- 如果没有说明可能是一个文本节点或者是注释节点。会创建一个dom元素。将el的内容放入里面
- 形成一个template模板。
- 然后将temp转换为render()函数。
- 当render()函数生成之后会存到options.render = render
- 最终会执行,mount方法
- 重新获取el, 因为带编译器版本的vue已经获取过el,如果是不带编译器版本的vue则需要重新获取el
- 进入mountComponent
- 判断当前选项中是否有render函数
- 因为这个是不带编译器的代码。如果有tempalate则会警告你需要编译器版本
- 因为如果是此时使用的编译器版本。这个时候模板已经编译成render()\
- 如果走到这个判断。options只有template的话。说明使用的是运行版本,并且使用了模板
- 使用callHook出发钩子函数。 callHook(vm, 'beforeMount')
- updateComponent, 调用vm._Render()
- _render()作用是调用用户传入的render()获取编译器编译的render()最终生成虚拟dom
- 将虚拟dom交给vm._update()将虚拟dom转换成真实dom,最后更新到页面上
- 创建一个watcher对象。进入watcher
- watcher有三种: 渲染watcher、计算属性的watcher, 监听器的watcher
- 首先判断是否是渲染watcher
- this.lazy 延迟执行。
- watcher是更新视图。而this.lazy判断是否延时更新视图。
- get方法把当前的watcher对象存到栈里面。
- 每个组件都会对应一个watcher,watcher会渲染对应的视图。
- 如果组件有嵌套的话会先渲染内部的组件。所以需要先把父级对应的watcher保存起来
- 接下来调用渲染getter,也就是调用updateCOmponent() ---> vm._undate()将render
- 象渲染到页面上。此处视图已经渲染完毕
- 最后首次渲染的过程完成。