使用虚拟 dom 渲染页面 《vue.js 设计与实现》
使用 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 设计与实现》的更多相关文章
- vue2.0的虚拟DOM渲染
1.为什么需要虚拟DOM 前面我们从零开始写了一个简单的类Vue框架(文章链接),其中的模板解析和渲染是通过Compile函数来完成的,采用了文档碎片代替了直接对页面中DOM元素的操作,在完成数据的更 ...
- 建立多页面vue.js项目
介绍 根据需求,我们希望建立一个多页面的vue.js项目,如何改造单页面vue.js项目为多页面项目?跟着我的步伐看下去吧. 1.创建单页面vue.js项目 简单的记录一下创建步骤: --安装cnpm ...
- [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 ...
- 简单实现react中虚拟DOM渲染
/** * @method createElement * @param type {string} * @param props {Object} * @param children {string ...
- Vue之虚拟DOM
一.真实DOM和其解析流程? 浏览器渲染引擎工作流程都差不多,大致分为5步,创建DOM树——创建StyleRules——创建Render树——布局Layout——绘制Painting 第一步,用HTM ...
- vue之虚拟DOM、diff算法
一.真实DOM和其解析流程? 浏览器渲染引擎工作流程都差不多,大致分为5步,创建DOM树——创建StyleRules——创建Render树——布局Layout——绘制Painting 第一步,用HTM ...
- 详解Vue中的虚拟DOM
摘要: 什么是虚拟DOM? 作者:浪里行舟 Fundebug经授权转载,版权归原作者所有. 前言 Vue.js 2.0引入Virtual DOM,比Vue.js 1.0的初始渲染速度提升了2-4倍,并 ...
- Vue.js 2.x render 渲染函数 & JSX
Vue.js 2.x render 渲染函数 & JSX Vue绝大多数情况下使用template创建 HTML.但是比如一些重复性比较高的场景,需要运用 JavaScript 的完全编程能力 ...
- 虚拟dom?diff算法?key?Vue原理的核心三问?打包教你搞定。
为什么需要虚拟DOM 先介绍浏览器加载一个HTML文件需要做哪些事,帮助我们理解为什么我们需要虚拟DOM.webkit引擎的处理流程,如下图所示: 所有浏览器的引擎工作流程都差不多,如上图大致分5步: ...
- 图解vue中 v-for 的 :key 的作用,虚拟dom Diff算法
其实不只是vue,react中在执行列表渲染时也会要求给每个组件添加上key这个属性. 要解释key的作用,不得不先介绍一下虚拟DOM的Diff算法了. 我们知道,vue和react都实现了一套虚拟D ...
随机推荐
- 由浅入深学习SAP财务 - 高林旭 PDF 版本
由浅入深学习SAP财务 - 高林旭 PDF 版本 有需要的联系 wx :erpworld
- Vue 的生命周期 详细解析(使用场景等)
Vue生命周期图: 一.生命周期图的解读 new Vue():首先需要创建一个 Vue的实例对象 Init Events & Lifecycle :初始化:生命周期.事件(如:v-once), ...
- 计数 dp 部分例题(一~五部分)
一.状态设计和简化(状態をまとめる) 例题1:Unhappy Hacking 题意 有一个空串,可以进行下面三种操作: 在末尾加入一个 \(0\). 在末尾加入一个 \(1\). 删去末尾的数,如果串 ...
- 【ESP32学习】CMake学习
在之前的博客中提到,ESP-IDF采用的是CMake来构建项目,因此需要学习一下CMake,以对ESP32的开发有更好的把握 参考: Windows下CMake安装教程 从零开始详细介绍CMake C ...
- 【读书笔记】Linux系统管理初学者指南读书笔记1——第1-2章
本博客记录一下<Linux系统管理初学者指南>这本书的读书笔记,最近由于想做一些关于嵌入式的项目,所以需要对Linux系统进行学习,正好之前买过这本书,内容还可以,能作为入门阅读 第1章 ...
- MySQL同步部分库注意的问题
同步部分库或部分库表 复制部分库:replicate_do_db 复制排除部分库:replicate_ignore_db 复制部分表:replicate_do_table 复制排除部分表:replic ...
- 通过nft持有大户地址获取正常交易和内部交易
/*内部交易*/------------ CREATE TABLE `internal_txlist` ( `blockNumber` varchar(255) DEFAULT NULL, `tx_t ...
- 2022-3-18内部群每日三题-清辉PMP
1.在评估项目活动现状的会议中,团队发现存在一些影响可交付成果的风险.项目经理应该怎么做? A.跟踪已发现的风险,识别和分析新风险,并评估整个项目的风险过程有效性 B.记录风险管理信息用于经验教训 C ...
- leecode 22 括号生成
22. 括号生成 数字 n 代表生成括号的对数,请你设计一个函数,用于能够生成所有可能的并且 有效的 括号组合. 示例 1: 输入:n = 3 输出:["((()))"," ...
- RN 使用react-native-video 播放视频(包含进度条、全屏)
21年12月3日,阐述上有问题:应该将问题拆分,不该将代码整一大堆,看着很不舒适 目标需求:1. 实现视频播放 2. 进度条 3. 进入全屏 目标图是这样的: 需要三个组件 1. 播放视频组件, re ...