IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> 从template---------->渲染函数都干了些什么 -> 正文阅读

[JavaScript知识库]从template---------->渲染函数都干了些什么

<深入浅出Vuejs>模板编译_解析器&优化器&生成器_V1RusCz的博客-CSDN博客?原文链接

在Vue中可以通过{{变量}}或者在里面写表达式,但是在html中为什么不行呢?在一个篇章中讲过

从:模板---------------->渲染函数------------------>vnode-------------------->视图。

编译模板的主要目的就是生成渲染函数,这个过程主要包含三个部分:

1.将模板字符串解析为AST(抽象语法树)

2.便利AST标记所有的静态节点(不需要重新渲染的节点)

3.使用AST生成渲染函数

以上三步分别对应模板编译中的三个模块:

1.解析器(Html解析器 文本解析器 过滤解析器)

2.优化器

3.代码生成器

让我们从vue.$mount函数开始,分别介绍以上三个模块的具体实现原理

1.解析器

<div>
<p>{{name}}</p>
</div>

{
  tag: "div"
  type: 1,
  staticRoot: false,
  static: false,
  plain: true,
  parent: undefined,
  attrsList: [],
  attrsMap: {},
  children: [
    {
      tag: "p"
      type: 1,
      staticRoot: false,
      static: false,
      plain: true,
      parent: {tag: "div", ...},
      attrsList: [],
      attrsMap: {},
      children: [{
        type: 2,
        text: "{{name}}",
        static: false,
        expression: "_s(name)"
      }]
    }
  ]
}

? 事实上,解析器又分了好多子解析器,如HTML解析器,文本解析器,过滤解析器等,其中最主要的就是HTML解析器,在其过程中会触发不同的构造函数(标签开始钩子,标签结束钩子,文本钩子,注释钩子)。

2.优化器

?通过解析器的处理,我们就得到了Vue模板的AST。由于Vue是响应式设计,所以拿到AST之后还需要进行一系列优化,确保静态的数据不会进入虚拟DOM的更新阶段,以此来优化性能。。

简单来讲,就是把静态节点的static属性设置为true,然后找到再便利一次找到静态根节点。

注意:静态节点的所有子节点都是静态节点,动态节点的父节点是动态节点,这个特征保证,我们找到的第一个静态节点会被标记为静态根节点,此时不用再遍历其子节点,因为他的子节点必然是静态节点

??

3.代码生成器

至此,我们已经得到了优化后的AST,我们只需要做一些简单的字符串拼接就能生成Render函数。

export function generate(ast, options) {
  const state = new CodegenState(options)
  const code = ast ? genElement(ast, state) : '_c("div")'
  return {
    render: `with(this){return ${code}}`,
    staticRenderFns: state.staticRenderFns
  }
}
 
export function genElement (el, state) {
  let code
  const data = genData(el, state)
  const children = genChildren(el, state, true)
  code = `_c('${el.tag}'${
    data ? `,${data}` : '' // data
  }${
    children ? `,${children}` : '' // children
  })`
  return code
}

生成的渲染函数效果如图:

<div>
  <h2 v-if="message">{{message}}</h2>
  <button @click="showName">showName</button>
</div>
with (this) {
    return _c(
      'div',
      [
        (message) ? _c('h2', [_v(_s(message))]) : _e(),
        _v(' '),
        _c('button', { on: { click: showName } }, [_v('showName')])
      ])
    ;
}

注意:

vm._c是创建DOM标签的

vm._v是创建文本节点的

vm._s就是toString

分析用render挂载的实例

import Vue from "vue";
import App from "./App.vue";

Vue.config.productionTip = false;


new Vue({
  render: (h) => h(App),
}).$mount("#app");

render函数是vue通过js渲染dom结构的函数createElement,约定可以简写为h

官方文档中是这样写的,createElement是Vue.js里面的函数。

这个函数的作用就是生成一个VNode节点,

render函数得到这个VNode节点之后

返回给Vue.js的mount函数,渲染成真实DOM节点,并挂载到个根节点上。

render函数跟template一样都是创建html模板的,但是有些场景中用template实现

起来代码冗长繁琐而且有大量重复,这个时候就可以用render函数。

由虚拟节点---------------------------->真实节点的一个过程。

总结:

1.解析器的主要功能就是将模板字符串转换为AST,解析器parse调用parseHtml函数用于循环解析模板字符串,并把不同类型的字符串调用相应的钩子函数(作用是维护层次栈以及建立AST),最终返回AST根节点。

2.优化器用于标记所有静态节点以及静态根节点? ? ? ??

3.代码生成器将优化获得AST转换为渲染函数? ?

  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2022-04-27 11:15:02  更:2022-04-27 11:17:34 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 0:58:36-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码