使用 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. 由浅入深学习SAP财务 - 高林旭 PDF 版本

    由浅入深学习SAP财务 - 高林旭  PDF 版本 有需要的联系 wx :erpworld

  2. Vue 的生命周期 详细解析(使用场景等)

    Vue生命周期图: 一.生命周期图的解读 new Vue():首先需要创建一个 Vue的实例对象 Init Events & Lifecycle :初始化:生命周期.事件(如:v-once), ...

  3. 计数 dp 部分例题(一~五部分)

    一.状态设计和简化(状態をまとめる) 例题1:Unhappy Hacking 题意 有一个空串,可以进行下面三种操作: 在末尾加入一个 \(0\). 在末尾加入一个 \(1\). 删去末尾的数,如果串 ...

  4. 【ESP32学习】CMake学习

    在之前的博客中提到,ESP-IDF采用的是CMake来构建项目,因此需要学习一下CMake,以对ESP32的开发有更好的把握 参考: Windows下CMake安装教程 从零开始详细介绍CMake C ...

  5. 【读书笔记】Linux系统管理初学者指南读书笔记1——第1-2章

    本博客记录一下<Linux系统管理初学者指南>这本书的读书笔记,最近由于想做一些关于嵌入式的项目,所以需要对Linux系统进行学习,正好之前买过这本书,内容还可以,能作为入门阅读 第1章 ...

  6. MySQL同步部分库注意的问题

    同步部分库或部分库表 复制部分库:replicate_do_db 复制排除部分库:replicate_ignore_db 复制部分表:replicate_do_table 复制排除部分表:replic ...

  7. 通过nft持有大户地址获取正常交易和内部交易

    /*内部交易*/------------ CREATE TABLE `internal_txlist` ( `blockNumber` varchar(255) DEFAULT NULL, `tx_t ...

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

    1.在评估项目活动现状的会议中,团队发现存在一些影响可交付成果的风险.项目经理应该怎么做? A.跟踪已发现的风险,识别和分析新风险,并评估整个项目的风险过程有效性 B.记录风险管理信息用于经验教训 C ...

  9. leecode 22 括号生成

    22. 括号生成 数字 n 代表生成括号的对数,请你设计一个函数,用于能够生成所有可能的并且 有效的 括号组合. 示例 1: 输入:n = 3 输出:["((()))"," ...

  10. RN 使用react-native-video 播放视频(包含进度条、全屏)

    21年12月3日,阐述上有问题:应该将问题拆分,不该将代码整一大堆,看着很不舒适 目标需求:1. 实现视频播放 2. 进度条 3. 进入全屏 目标图是这样的: 需要三个组件 1. 播放视频组件, re ...