使用 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对象中回包含多种数据字段,每个字段都代表一定的含义。

最新文章

  1. python --&gt; 递归 以及装饰器
  2. 《JS设计模式笔记》 1,单例模式
  3. VS2010开发AutoCAD 2012 .net应用程序调试时断点不起作用
  4. join()方法
  5. 003.同时Ping多个IP(select实现IO复用,信号计时),ping程序升级版
  6. THE SENSE OF BEAUTY
  7. 转 java int与Integer的区别
  8. 消息队列之RabbitMQ
  9. ui/ue设计师应该了解的原型设计软件
  10. POJ 3177 Redundant Paths(强连通分量)
  11. Windows与Linux下文件操作监控的实现
  12. CodeForces 701C They Are Everywhere(map的应用)
  13. iOS学习——UIView的研究
  14. visual studio 2010 Error: IntelliSense: identifier &quot;DWORD&quot; is undefined
  15. (2) linux文件系统简介
  16. OkHttp踩坑记:为何 response.body().string() 只能调用一次?
  17. easyui combobox 动态加载数据C#
  18. Spring的AOP配置文件和注解实例解析
  19. netcore的Session使用小记
  20. javascript公有静态成员

热门文章

  1. 第6课第4节_Binder系统_驱动情景分析_服务注册过程_分析
  2. unity shader ide
  3. KEIL5中C/C++优化等级问题
  4. 3.Linux安装docker
  5. vue 报错Uncaught (in promise) cancel
  6. 2022-04-25内部群每日三题-清辉PMP
  7. 2022-3-8内部群每日三题-清辉PMP
  8. vue v-for 循环中,下拉框 el select 设置初始值 v-model
  9. Pytest Fixture(三)
  10. C语言的所有函数