文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Vue.js设计与实现之Vue.js3的设计思路

2024-12-02 04:11

关注

2.声明式描述UI

通过前面的介绍,我们知道Vue.js3是声明式UI框架,作者是如何参与设计一个声明式的UI框架,编写前端页面又涉及到哪些内容?

上面这些内容是原生包含的,进行框架设计时如何让它们变成响应式的,在Vue.js3中的解决方案是:

这样,使用者不需要手写任何命令式代码,就可以实现声明式描述UI。当然除了使用模板形式描述UI外,还能使用JS对象来描述:

const element = {
//标签元素
tag: "div",
//标签属性
props:{
onClick: handleClick
},
//子节点
children: [
{ tag:"span" }
]
}

对应的template模板是:

使用js数据对象描述和template模板有什么异同呢?

//h标签的限制
const level = 3;
const element = {
tag: `h${level}`,//h3标签
}

我们看到对于js对象结构代码简洁清晰,而使用模板则需要进行穷举:






我们在Vue.js组件中通过手写渲染函数就是使用虚拟DOM来描述UI,h函数的返回值就是一个对象,用于开发者轻松地使用虚拟DOM描述UI。

import {h} from "vue";

export default {
render(){
return h("div",{ onClick: handleClick })//虚拟DOM
}
}

对应的JS对象描述UI就是如下代码段:

export default {
render(){
return {
tag:"div",
props:{onClick: handleClick }
}
}
}

组件的渲染函数renderer的作用:Vue.js根据组件的render函数的返回值生成虚拟DOM,进而将组件内容进行渲染到页面。

3.初识渲染器

我们可以使用JS数据对象来描述虚拟DOM,那么虚拟DOM又是如何通过渲染函数转为真实DOM后,渲染到页面的呢?

在前面的代码片段中是使用JS数据对象来描述虚拟DOM:

const vnode = {
tag:"div",
props:{
onclick:()=>console.log("hello pingping")
},
children:"please click me"
}

我们需要编写渲染函数renderer去将虚拟DOM渲染为真实DOM,接收两个参数:vnode虚拟DOM对象以及container真实DOM元素挂载点,container用于挂载渲染函数渲染的真实DOM元素。

function renderer(vnode, container){
// 使用vnode的tag作为标签名渲染DOM元素
const el = document.createElement(vnode.tag)
// 遍历vnode的props作为DOM元素的属性和事件
for(const key in vnode.props){
if(/^on/.test(key)){
// 如果key以on开头,这说明他是一个事件
el.addEventListener(
key.substring(2).toLowerCase(),//事件名称将onClick-->click
vnode.props[key]//事件处理函数
)
}
}

// 处理children
if(typeof vnode.children === "string"){
// 如果是字符串,直接作为元素的文本子节点
el.appendChild(document.createTextNode(vnode.children))
}else if(Array.isArray(vnode.children)){
// 递归调用renderer函数进行渲染子节点,使用当前元素el作为挂载点
vnode.children.forEach(child=>renderer(child,el))
}
// 将元素添加到挂载点
container.appendChild(el)
}

调用:

renderer(vnode, document.body)

点击按钮后:

渲染器renderer的实现思路:

4.组件的本质

组件是一组DOM元素的封装,而这组DOM元素就是组件渲染的内容,对此可以定义函数来描述这段真实DOM元素对应的虚拟DOM对象。

const MyComponent = function(){
return {
tag:"div",
props:{
onClick: ()=>console.log("hello world")
},
children:"click me"
}
}

通过虚拟DOM对象中tag属性可以用于存储组件函数,将其作为标签类型进行渲染,同样的也需要渲染器renderer函数。当然,此时的渲染函数需要根据待渲染标签的类型进行判定,是普通标签元素还是组件元素。

const vnode = {
tag: MyComponent
}

renderer(vnode, document.body)

function renderer(vnode, container){
// 判断是标签元素还是组件
if(typeof vnode.tag === "string"){
// 如果是字符串,直接作为元素的标签元素
mountElement(vnode, container)
}else{
mountComponent(vnode, container)
}
}

// 渲染元素
function mountElement(vnode, container){
// 使用vnode.tag 作为标签名称创建DOM元素
const el = document.createElement(vnode.tag)
// 遍历vnode的props作为DOM元素的属性和事件
for(const key in vnode.props){
if(/^on/.test(key)){
// 如果key以on开头,这说明他是一个事件
el.addEventListener(
key.substring(2).toLowerCase(),//事件名称将onClick-->click
vnode.props[key]//事件处理函数
)
}
}

// 处理children
if(typeof vnode.children === "string"){
// 如果是字符串,直接作为元素的文本子节点
el.appendChild(document.createTextNode(vnode.children))
}else if(Array.isArray(vnode.children)){
// 递归调用renderer函数进行渲染子节点,使用当前元素el作为挂载点
vnode.children.forEach(child=>renderer(child,el))
}
// 将元素添加到挂载点
container.appendChild(el)
}

// 渲染组件
function mountComponent(vnode, container){
// 调用组件函数,获取组件要渲染的内容-虚拟DOM
const subtree = vnode.tag()
// 递归调用renderer渲染subtree
renderer(subtree, container)
}

5.模板的工作原理

其实,手写虚拟DOM还是使用模板形式,都可以声明式描述UI,在Vue.js框架设计中是始终支持两种形式的。我们知道JS对象描述虚拟DOM的形式,是通过渲染器renderer将虚拟DOM转为真实DOM的,那么模板又是如何渲染到页面的呢?


hello pingping

模板字符串渲染到页面,依赖于

模板字符串渲染到页面,依赖于Vue.js框架的一个重要函数--编译器compiler,其作用就是将模板字符串编译成与之功能对应的渲染函数:

render(){
return h("div",{onClick: handleClick},"hello pingping")
}

对此,我们知道无论是使用模板字符串还是直接手写渲染函数,都是通过渲染函数将虚拟DOM转为真实DOM,最终将描述的内容渲染到页面上。只不过使用模板字符串多了一个编译过程,需要通过编译器将模板字符串编译成渲染函数。

6.编译器和渲染器组成有机整体

在Vue.js框架设计中,组件实现依赖于渲染器和编译器,而渲染器和编译器之间是彼此独立又相互依赖的重要部分。

7.写在后面

本文中,我们了解到Vue.js框架是通过声明式描述UI的,而描述UI又有两种形式:模板字符串和手写虚拟DOM的形式,虚拟DOM形式比模板字符串更加灵活,但是模板字符串比虚拟DOM形式更加直观。

在Vue.js框架设计中有两种重要的组成部分:编译器和渲染器,编译器就是将模板字符串编译成渲染函数,而渲染器则是将虚拟DOM创建为真实DOM,最终完成页面的渲染。

来源:前端一码平川内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯