使用 js 对象描述 ui 更加灵活。假如我们要根据级别不同采用不同的标签。js 对象描述的话,只需要一个变量代表 h 标签即可。

// 当变量改变时,标签也会变化。
let level = 3
const title = {
tag: `h${level}` //h3
}
<h1 v-if="level === 1"></h1>
<h2 v-else-if="level === 2"></h2>
<h3 v-else-if="level === 3"></h3>
<h4 v-else-if="level === 4"></h4>
<h5 v-else-if="level === 5"></h5>
<h6 v-else-if="level === 6"></h6>

  这远没有 js 对象灵活。其实就是所谓的虚拟 dom.vuejs 3 除了支持使用模板描述 ui 外,还支持使用虚拟 dom 描述 ui.其实我们在 vue.js 组建中手写的渲染函数就是使用虚拟 dom 来描述 ui 的。

import { h } from 'vue'

export default {
render() {
return h('h1', { onClick: handler })
}
}

  渲染器的工作原理其实很简单,归根到底,都是使用一些我们熟悉的 DOM 操作 API 来完成渲染工作。渲染器的精髓都在更新节点的阶段。组件就是一组 dom 元素的封装,这组 dom 元素就是组件要渲染的内容,因此我们可以定义一个函数来代表组件。组件的返回值也是虚拟 dom,它代表组件要渲染的内容。搞清楚啦组件的本质,我们就可以定义用虚拟 dom 来描述组件来。

const MyComponent = function () {
return {
tag: 'div',
props: {
onClick: () => alert('hello')
},
children: 'click me'
}
} const vnode = {
tag: MyComponent
} function renderer(vnode, container) {
if (typeof vnode.tag === 'string') {
// vnode描述的是标签元素
mountElement(vnode, container)
} else if (typeof vnode.tag === 'function') {
// vnode描述的是组件
mountComponent(vnode, container)
}
} function mountElement(vnode, container) {
const el = document.createElement(vnode.tag) for (const key in vnode.props) {
if (/^on/.test(key)) {
el.addEventListener(key.substr(2).toLowerCase(), vnode.props[key])
}
} if (typeof vnode.children === 'string') {
el.appendChild(document.createTextNode(vnode.children))
} else if (Array.isArray(vnode.children)) {
vnode.children.forEach((child) => renderer(child, el))
} container.appendChild(el)
}

  无论是手写虚拟 dom(渲染函数)还是使用模板,都属于声明式描述 ui,并且 vue.js 同时支持这两种描述 ui 的方式。编译器和渲染器一样,只是一段程序而已,不过它们的工作内容不同。编译器的作用其实就是将模版编译为渲染函数。

  无论使用模版还是直接手写渲染函数,对于一个组件来说,它要渲染的内容最终都是通过渲染函数产生的,然后渲染器再把渲染函数返回的虚拟 dom 渲染为真实 dom,这就是模版的工作原理,也是 vue.js 渲染页面的流程。

  编译器能识别出哪些是静态属性,哪些是动态属性,在生成代码的时候完全可以附带这些信息:

render(){
return {
tag:'div',
props:{
id:'foo',
class:cls
},
patchFlag:1 // 假设数字1代表class是动态的
}
}

  在生成的虚拟dom对象中多处啦一个patchFlags属性,假设1代表class是动态的,这样渲染器看到这个标志时就知道。省去啦寻找变更点的工作,性能就提升啦。编译器和渲染器之间时存在信息交流的,它们互相配合使得性能进一步提升,而它们之间交流的媒介就是虚拟dom对象。一个虚拟dom对象中回包含多种数据字段,每个字段都代表一定的含义。

使用虚拟 dom 渲染页面 《vue.js 设计与实现》的更多相关文章

  1. vue2.0的虚拟DOM渲染

    1.为什么需要虚拟DOM 前面我们从零开始写了一个简单的类Vue框架(文章链接),其中的模板解析和渲染是通过Compile函数来完成的,采用了文档碎片代替了直接对页面中DOM元素的操作,在完成数据的更 ...

  2. 建立多页面vue.js项目

    介绍 根据需求,我们希望建立一个多页面的vue.js项目,如何改造单页面vue.js项目为多页面项目?跟着我的步伐看下去吧. 1.创建单页面vue.js项目 简单的记录一下创建步骤: --安装cnpm ...

  3. [Vue] Conditionally Render DOM Elements in Vue.js (v-if v-else v-show)

    You can use v-if and v-else to display content based on assertions on your data. Similarly, v-show c ...

  4. 简单实现react中虚拟DOM渲染

    /** * @method createElement * @param type {string} * @param props {Object} * @param children {string ...

  5. Vue之虚拟DOM

    一.真实DOM和其解析流程? 浏览器渲染引擎工作流程都差不多,大致分为5步,创建DOM树——创建StyleRules——创建Render树——布局Layout——绘制Painting 第一步,用HTM ...

  6. vue之虚拟DOM、diff算法

    一.真实DOM和其解析流程? 浏览器渲染引擎工作流程都差不多,大致分为5步,创建DOM树——创建StyleRules——创建Render树——布局Layout——绘制Painting 第一步,用HTM ...

  7. 详解Vue中的虚拟DOM

    摘要: 什么是虚拟DOM? 作者:浪里行舟 Fundebug经授权转载,版权归原作者所有. 前言 Vue.js 2.0引入Virtual DOM,比Vue.js 1.0的初始渲染速度提升了2-4倍,并 ...

  8. Vue.js 2.x render 渲染函数 & JSX

    Vue.js 2.x render 渲染函数 & JSX Vue绝大多数情况下使用template创建 HTML.但是比如一些重复性比较高的场景,需要运用 JavaScript 的完全编程能力 ...

  9. 虚拟dom?diff算法?key?Vue原理的核心三问?打包教你搞定。

    为什么需要虚拟DOM 先介绍浏览器加载一个HTML文件需要做哪些事,帮助我们理解为什么我们需要虚拟DOM.webkit引擎的处理流程,如下图所示: 所有浏览器的引擎工作流程都差不多,如上图大致分5步: ...

  10. 图解vue中 v-for 的 :key 的作用,虚拟dom Diff算法

    其实不只是vue,react中在执行列表渲染时也会要求给每个组件添加上key这个属性. 要解释key的作用,不得不先介绍一下虚拟DOM的Diff算法了. 我们知道,vue和react都实现了一套虚拟D ...

随机推荐

  1. Spring事务注意事项 以及 遇到的坑

    原创参考: https://www.cnblogs.com/yougewe/p/7466677.html   (Spring,为内部方法新起一个事务,此处应有坑.) https://blog.csdn ...

  2. Django——全局配置settings详解

    Django设置文件包含你所有的Django安装配置.这个文件一般在你的项目文件夹里.比如我们创建了一个名为mysite的项目,那么这个配置文件setting.py就在项目里的mysite文件夹里. ...

  3. Day 22 22.1.1:增量式爬虫 - 场景1的实现

    场景1的实现: 数据指纹: 数据的唯一标识.记录表中可以不直接存储数据本身,直接存储数据指纹更好一些. 创建爬虫爬虫文件: cd project_name(进入项目目录) scrapy genspid ...

  4. 多个el-table在使用v-if在同一页面切换渲染时相互影响的解决办法

    解决办法 给每个el-table设置一个唯一的key值,如: <el-table key='uniqueName' ></el-table> <el-table key= ...

  5. 访问远程服务-RPC 与 REST

    方法调用 所做的传递参数.传回结果都依赖于栈内存.所以Caller 调用者 Callee 被调用者应该同属一个进程,拥有相同的 栈内存, 进程间通信(Inter-Process Communicati ...

  6. python实现PDF转PNG

    说明 为了方便将pdf格式发票转为图片,找到以下方法,转换后的效果非常不错,特此记录在自己的笔记中,根据自己的需要,代码稍微有所优化修改 参考网址:https://zhuanlan.zhihu.com ...

  7. 2022-3-17内部群每日三题-清辉PMP

    1.一个项目预算为6000万美元,预计需要24个月才能完成.12个月后,该项目完成了60%,并使用了3500美元.那么预算和进度的状态如何? A.符合预算,并超前于进度 B.超出预算,但超前于进度 C ...

  8. 2022-3-11内部群每日三题-清辉PMP

    1.供应商通知项目经理可能延迟交付一个模块.项目经理应该怎么做? A.立即通知相关方. B.通过增加额外的天数来修改项目管理计划,并记录它们对项目时间的影响. C.审查风险管理计划以评估风险,然后通知 ...

  9. echart 悬浮窗超边界了怎么办?

    悬浮窗超边界了怎么办? 在渲染界面函数里面 写一个 // tooltip浮窗未知 chartOption.tooltip.position = function(point, params, dom, ...

  10. LeetCode 删除数组中重复项 26 80

    26(80) 给你一个 升序排列 的数组 nums ,请你 原地 删除重复出现的元素,使每个元素只出现一次(使得出现次数超过两次的元素只出现两次 ) ,返回删除后数组的新长度.元素的 相对顺序 应该保 ...