超详细的Vue渲染原理讲解

目录

  • 一、Vue简介
    • 1. MVVM、MVP和MVC
    • 2. Vue的基本配置
  • 二、Vue渲染原理
    • 1. HTML与模板
    • 2. Vue组件的完整渲染过程
      • (1). Vue自身的初始化阶段
      • (2). 组件实例的生命周期管理阶段
        • a. 实例初始化阶段
        • b. 组件挂载、更新和销毁阶段
  • 总结

本文的主要内容是详细地介绍Vue的内部渲染原理,从而帮助大家深入掌握关于Vue Options、生命周期等概念。为了帮助Vue使用经验较少的同学快速理解Vue,我们先从Vue的简介开始,第二部分再详细介绍Vue渲染原理。

一、Vue简介

1. MVVM、MVP和MVC

MVVM,即model、view、view-model,业务层、视图层以及两者的绑定层。Vue的设计参考了MVVM架构,但不完全是一个MVVM框架,因为它没有严格意义上的绑定层。

MVVM要求开发者将业务层和视图层分开:业务层负责管理数据;视图层负责页面渲染;绑定层负责双向绑定,即视图层操作通过绑定层影响业务数据,业务数据的变化通过绑定层影响视图渲染,这三层是完全解耦的:
超详细的Vue渲染原理讲解_第1张图片
举个例子,假如我们的页面有一个h1标题,它要渲染的是js中变量title的值:

<h1>这是标题</h1>

<script>
  let title = '这是标题';
</script>

这里h1的文本内容就是由view层管理的;而model层负责的是管理业务数据title。现在viewmodel层都有了,下面我们就要让h1的文本内容和title的内容保持同步,这就是view-model层要做的事。假设我们有这样一个xml文件:

<h1>{
     {
     title}}</h1>

它表示h1的文本和变量title的值是绑定的,当一个发生变化时,另一个应该同步变化。

如果我们能够编写一个框架,自动根据一个值,更新另一个值,那么实际上就是实现了view-model层,我们的框架就可以称为一个MVVM框架。以后只要我们定义好视图和业务逻辑,并用一个xml文件描述两者的绑定关系,就可以实现视图和数据的同步了,这也是谷歌的Data Binding的基本实现思路。

MVVM模式参考自MVP模式,而两者都是借鉴自经典的MVC模式。先来说说MVVM和MVP的差异。

MVP的全写是Model-View-Presenter,即业务层、视图层和控制层。这里的控制层Presenter与view-model层的作用是完全一样的,就是负责对视图层和业务层进行同步。但不同的是,Presenter的实现较为复杂,它要求开发者必须手动封装两者的同步逻辑,如jQuery框架就可以看做一个MVP模式的实现:

<h1></h1>

<script>
  let title = '这是标题';

  $('h1').text(title);
</script>

开发者需要定义当变量变化时如何更新视图,以及获取到用户输入时如何更新变量,这两者加起来就是它的Presenter层实现。这种方式也可以实现视图和业务逻辑的同步,但显然,MVP的控制层逻辑要比MVVM的声明式绑定写起来复杂得多,所以MVP模式基本上已经被MVVM代替。

而MVC是上述两个模式的鼻祖,也曾是java中最经典的模式之一,它的全写是Model-View-Controller。model和view层与上述两个模式一致,controller层与MVP的Presenter层一样,也被称作控制层。不过,MVC中的controller功能很弱,它实际上只是一个路由层,真正实现视图与业务数据同步的是model层的service,controller的作用就是找到对应的service而已。controller层的功能过于薄弱使得model层变得很复杂,所以目前MVC模式已经很少使用。

Vue之所以不是一个MVVM框架,是因为它没有真正的view-model层。在Vue中,view-model是通过模板语法间接实现的,Vue通过编译模板,可以解析出视图层和业务层的绑定关系,通过响应式系统和虚拟DOM来实现两者的同步,详细的过程后面会加以介绍。

2. Vue的基本配置

由于讲解Vue配置不是本文的重点,这里我们只是简单地概括一下,需要详细学习这部分内容的可以阅读Vue的官方文档:Vue官方网站。

为了简单,我们先以一个cdn版本的Vue为例:

<script type="text/javascript" src="https://unpkg.com/vue"></script>

<div id="app"></div>

<script>
  let app = new Vue({
     
    el: '#app',
    data: {
      title: '标题' },
    template: '

{ {title}}

'
, methods: { changeTitle (title) { this.title = title; } } }); setTimeout(function () { app.changeTitle('新标题'); }, 1000); </script>

执行完script脚本对应的框架代码后,window上会新增一个构造函数Vue,用于构建Vue实例。我们向new Vue传入了一个配置对象,这个对象包含如el、data、template、methods等属性,用于为Vue实例添加属性和方法。Vue会根据这些配置,生成一个可以自动生成视图的响应式的Vue组件,它不仅负责管理视图层和业务层,还负责两者的同步。

我们来简单看一下一些常用配置的作用:

  1. el
    根元素,该参数只能由根节点声明,表示当前Vue应用需要被挂载到页面的哪个DOM节点上。如上面的例子指定了根元素为#app,那么该Vue实例生成的DOM就会直接替换id为app的元素。
  2. name
    组件的名字,主要用于全局注册组件,如:
import MyComponent from 'MyComponent';
Vue.component(MyComponent.name, MyComponent);
  1. components
    声明当前组件的外部依赖,相当于局部注册组件,在编写单组件时,如果需要用到其他的项目内组件通常会提供该参数。
  2. props
    来自父级组件的数据依赖,这个依赖是响应式的。
  3. data
    业务数据,这个参数是model层的核心,相关的业务逻辑都是围绕data展开的。
  4. computed
    计算属性,定义一组变量,这组变量的值是基于一个或多个props、data计算而来,computed内变量的值会根据这些依赖的值变化而自动更新,并且会自动缓存上次的计算结果。
  5. watch
    手动监控props、data或者computed的变化,定义变化时的回调函数。
  6. 生命周期方法
    定义Vue组件在各个生命周期需要执行的回调函数,Vue在执行到对应的阶段时会调用它们。生命周期与Vue组件创建的细节是第二部分渲染原理的重点。
  7. methods
    组件的工具方法集。methods定义了一组工具方法,可以在computed、watch、生命周期方法或者其他工具方法中调用。

有了这些基本知识的铺垫,下面我们就开始详细介绍Vue的渲染过程。

二、Vue渲染原理

我们先来打通HTML与Vue模板的关系。

1. HTML与模板

下面是一个常见的Vue例子:
超详细的Vue渲染原理讲解_第2张图片
整个Vue应用被挂载到页面上id为app的节点上,传入的模板字符串是。Vue会解析组件App的模板来替换该标签。在解析App的模板时发现它又引入了另一个组件MyComponent,于是Vue继续解析MyComponent的模板,将解析结果替换到App组件模板内。全部解析之后会得到这样一个模板:

<template>
  <div id="a">
    <p>111</p>
    
    <div id="comp">
      <h1>222</h1>
      <p>333</p>
    </div>
    
  </div>
</template>

注意,这并不是HTML代码,它仍然是Vue模板(只是这里没有定义数据绑定而已)。Vue会用纯JavaScript来描述上述结构,类似下面这样(这不是真正的内部表示,后面我们会看到Vue的真实内部表示):
超详细的Vue渲染原理讲解_第3张图片
这里最外部id为app的节点实际上是不存在的,Vue在生成DOM时会替换掉该元素。

我们看到,Vue用一个JavaScript对象描述了编译出来的模板(如果有数据绑定,它还会描述模板与数据的绑定关系)。接下来只需要调用原生的DOM方法依次创建这里的每一个节点,然后将它们挂载成一棵DOM子树,并插入页面,就可以得到真正的HTML。我们一般把这个树状JavaScript对象称为虚拟DOM树。下面是上面的JavaScript对象对应的DOM结构:
超详细的Vue渲染原理讲解_第4张图片
也就是说,通过模板可以得到真实HTML的JavaScript对象表示,然后调用原生的DOM方法,借助这个JavaScript对象去生成真实的HTML。不仅如此,在这个过程中,Vue还注入了响应式系统,可以根据数据变化自动更新视图,以及根据视图自动更新数据,下面我们来讲解具体的实现过程。

2. Vue组件的完整渲染过程

Vue的执行过程主要分两大阶段:Vue自身的初始化阶段和实例的生命周期管理阶段。

当通过

你可能感兴趣的:(vue,Vue,渲染原理)