vue3组件化开发页面之渲染函数实现

文章目录

  • 前言
  • 一、渲染机制
    • 虚拟 DOM
    • 渲染管线
  • 二、渲染函数
    • 基本用法
    • 声明渲染函数
    • Vnodes 必须唯一
  • 三、页面使用渲染函数及组件配置
  • 总结
    • `如有启发,可点赞收藏哟~`


前言

组件化开发是目前开发的常态
本文记录页面拆分多个不同组件模块,然后再基于渲染函数实现页面的开发过程


一、渲染机制

由于渲染函数是基于虚拟DOM实现的,咱先简单了解渲染函数的背景

虚拟 DOM

虚拟 DOM (Virtual DOM,简称 VDOM) 是一种编程概念,意为将目标所需的 UI 通过数据结构“虚拟”地表示出来,保存在内存中,然后将真实的 DOM 与之保持同步。这个概念是由 React 率先开拓,随后被许多不同的框架采用,当然也包括 Vue。

与其说虚拟 DOM 是一种具体的技术,不如说是一种模式,所以并没有一个标准的实现。例如以下代码为纯 JavaScript 的对象 (一个“虚拟节点”),它代表着一个 <div> 元素

const vnode = {type: 'div',props: {id: 'hello'},children: [/* 更多 vnode */]
}

渲染管线

  • 编译:Vue 模板被编译为渲染函数:即用来返回虚拟 DOM 树的函数。这一步骤可以通过构建步骤提前完成,也可以通过使用运行时编译器即时完成。

  • 挂载:运行时渲染器调用渲染函数,遍历返回的虚拟 DOM 树,并基于它创建实际的 DOM 节点。这一步会作为响应式副作用执行,因此它会追踪其中所用到的所有响应式依赖。

  • 更新:当一个依赖发生变化后,副作用会重新运行,这时候会创建一个更新后的虚拟 DOM 树。运行时渲染器遍历这棵新树,将它与旧树进行比较,然后将必要的更新应用到真实 DOM 上去。

结合上文可以看出,如果使用渲染函数会比 使用Vue模版渲染更快,因为少了一个编译的步骤

二、渲染函数

在绝大多数情况下,Vue 推荐使用模板语法来创建应用。然而在某些使用场景下,我们真的需要用到 JavaScript 完全的编程能力。这时渲染函数就派上用场了。

基本用法

h() 是 hyperscript 的简称——意思是“能生成 HTML (超文本标记语言) 的 JavaScript”。这个名字来源于许多虚拟 DOM 实现默认形成的约定。一个更准确的名称应该是 createVnode(),但当你需要多次使用渲染函数时,一个简短的名字会更省力。

  • 创建 Vnodes
  • Vue 提供了一个 h() 函数用于创建 vnodes:
import { h } from 'vue'const vnode = h('div', // type{ id: 'foo', class: 'bar' }, // props[/* children */]
)
// 除了类型必填以外,其他的参数都是可选的
h('div')
h('div', { id: 'foo' })// attribute 和 property 都能在 prop 中书写
// Vue 会自动将它们分配到正确的位置
h('div', { class: 'bar', innerHTML: 'hello' })// 像 `.prop` 和 `.attr` 这样的的属性修饰符
// 可以分别通过 `.` 和 `^` 前缀来添加
h('div', { '.name': 'some-name', '^width': '100' })// 类与样式可以像在模板中一样
// 用数组或对象的形式书写
h('div', { class: [foo, { bar }], style: { color: 'red' } })// 事件监听器应以 onXxx 的形式书写
h('div', { onClick: () => {} })// children 可以是一个字符串
h('div', { id: 'foo' }, 'hello')// 没有 props 时可以省略不写
h('div', 'hello')
h('div', [h('span', 'hello')])// children 数组可以同时包含 vnodes 与字符串
h('div', ['hello', h('span', 'hello')])

声明渲染函数

可以使用 render 选项来声明渲染函数:

import { h } from 'vue'export default {data() {return {msg: 'hello'}},render() {return h('div', this.msg)}
}

除了返回一个单独的 vnode 之外,你还可以返回字符串或是数组:

export default {render() {return 'hello world!'}
}
import { h } from 'vue'export default {render() {// 用数组来返回多个根节点return [h('div'),h('div'),h('div')]}
}

Vnodes 必须唯一

组件树中的 vnodes 必须是唯一的。

如果你真的非常想在页面上渲染多个重复的元素或者组件,你可以使用一个工厂函数来做这件事。比如下面的这个渲染函数就可以完美渲染出 20 个相同的段落:

function render() {return h('div',Array.from({ length: 20 }).map(() => {return h('p', 'hi')}))
}

三、页面使用渲染函数及组件配置

把一个页面拆分多个组件模块,以组装形式依次生成
可以使用Wrapper 组件包装下,处理多个路由通用逻辑

  • wrapper/index.vue
<template><slot></slot>
</template><script lang="ts" src="./index.ts" /><style lang="less" scoped></style>
  • user-sreach/index.vue
<template><div>user sreach</div>
</template><style scoped lang="less"></style>
  • user-list/index.vue
<template><div>user list</div>
</template><style scoped lang="less"></style>
  • /user/index.ts
import { ROUTER_CONFIG_MAP } from '@/const/router';
import { defineComponent, h, defineAsyncComponent, type Component } from 'vue';const Wrapper = defineAsyncComponent(() => import('@/components-business/wrapper/index.vue'));
const UserSreach = defineAsyncComponent(() => import('@/components-business/form/user-sreach/index.vue'));
const UserList = defineAsyncComponent(() => import('@/components-business/table/user-list/index.vue'));const componentsMap: Types.KeyMapAny<Component> = {UserSreach,UserList
};const pageComponent = ['UserSreach','UserList'
]
export default defineComponent({// 配置后可在 动态获取路由配置中设置对应值name: ROUTER_CONFIG_MAP.system.user.name,title: ROUTER_CONFIG_MAP.system.user.title,path: ROUTER_CONFIG_MAP.system.user.path,setup() {// return () => pageComponent.map((item: string) => componentsMap[item] ? h(componentsMap[item]) : null);return () => h(Wrapper,null,() => pageComponent.map((item: string) => componentsMap[item] ? h(componentsMap[item]) : null));},
});
  • router/index.ts
import { createRouter, createWebHistory } from "vue-router";
const router = createRouter({history: createWebHistory(import.meta.env.BASE_URL),routes: [{path: "/",name: "Home",component: () => import('@/views/contents-pages/system/user/index'),},],
});export default router;

在这里插入图片描述


总结

如有启发,可点赞收藏哟~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/208721.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

const修饰

const 起保护作用&#xff0c;禁止修改。 此时a变为常量&#xff0c;常量不可修改。 const放在*p的左端限制*p&#xff0c;即不能通过修改指针变量&#xff08;*p&#xff09;的值来修改p指向空间的内容&#xff0c;但p不受限制。 const放在*的右端限制p&#xff0c;即不能修…

Unity 三维场景的搭建 软件构造实验报告

实验2&#xff1a;仿真系统功能实现 1.实验目的 &#xff08;1&#xff09;熟悉在Unity中设置仿真场景&#xff1b; &#xff08;2&#xff09;熟悉在Unity中C#语言的使用&#xff1b; &#xff08;3&#xff09;熟悉仿真功能的实现。 2.实验内容 新建一个仿真场景&#x…

中职组网络安全 Server-Hun-1.img Server-Hun-2.img

一串密码 smbuser用户和密码登录ssh还是失败提示需要密钥&#xff0c;尝试ftp登录成功 发现密钥存放在.ssh/下&#xff0c;在kali上生成一个密钥&#xff0c;通过上传到.ssh/下&#xff0c;将其替换掉 使用kali生成密钥 登录成功,但是无法拿到root目录下的flag 获取root用户权限…

《QT从基础到进阶·三十七》QWidget实现左侧导航栏效果

NavigationBarPlugin插件类实现了对左侧导航栏的管理&#xff0c;我们可以在导航栏插件中添加界面&#xff0c;并用鼠标点击导航栏能够切换对应的界面。 源码在文章末尾 实现效果如下&#xff1a; NavigationBarPlugin实现的接口如下&#xff1a; class NAVIGATIONBAR_EXP…

Nevron Vision for .NET 2023.1 Crack

Nevron Vision for .NET 适用于桌面和 Web 应用程序的高级数据可视化 Nevron Vision for .NET提供最全面的组件&#xff0c;用于构建面向 Web 和桌面的企业级数据可视化应用程序。 该套件中的组件具有连贯的 2D 和 3D 数据可视化效果&#xff0c;对观众产生巨大的视觉冲击力。我…

3.Gin 框架中的路由简要说明

3.Gin 框架中的路由简要说明 Gin 框架中的路由 路由概述 路由&#xff08;Routing&#xff09;是由一个 URI&#xff08;或者叫路径&#xff09;和一个特定的 HTTP 方法&#xff08;GET、POST 等&#xff09; 组成的&#xff0c;涉及到应用如何响应客户端对某个网站节点的访问。…

SpringBoot——启动类的原理

优质博文&#xff1a;IT-BLOG-CN SpringBoot启动类上使用SpringBootApplication注解&#xff0c;该注解是一个组合注解&#xff0c;包含多个其它注解。和类定义SpringApplication.run要揭开SpringBoot的神秘面纱&#xff0c;我们要从这两位开始就可以了。 SpringBootApplicati…

VUE语法-$refs和ref属性的使用

1、$refs和ref属性的使用 1、$refs:一个包含 DOM 元素和组件实例的对象&#xff0c;通过模板引用注册。 2、ref实际上获取元素的DOM节点 3、如果需要在Vue中操作DOM我们可以通过ref和$refs这两个来实现 总结:$refs可以获取被ref属性修饰的元素的相关信息。 1.1、$refs和re…

解决ElementUI时间选择器回显出现Wed..2013..中国标准时间.

使用饿了么组件 时间日期选择框回显到页面为啥是这样的&#xff1f; 为什么再时间框中选择日期&#xff0c;回显页面出现了这种英文格式呢&#xff1f;&#xff1f;&#xff1f;&#xff1f; 其实这个问题直接使用elementui的内置属性就能解决 DateTimePicker 日期时间选择…

搭个网页应用,让ChatGPT帮我写SQL

大家好&#xff0c;我是凌览。 开门见山&#xff0c;我搭了一个网页应用名字叫sql-translate。访问链接挂在我的个人博客(https://linglan01.cn/about)导航栏&#xff0c;也可以访问https://www.linglan01.cn/c/sql-translate/直达sql-translate。 它的主要功能有&#xff1a;…

Linux上通过SSL/TLS和start tls连接到LDAP服务器

一&#xff0c;大致流程。 1.首先在Linux上搭建一个LDAP服务器 2.在LDAP服务器上安装CA证书&#xff0c;服务器证书&#xff0c;因为SSL/TLS&#xff0c;start tls都属于机密通信&#xff0c;需要客户端和服务器都存在一个相同的证书认证双方的身份。3.安装phpldapadmin工具&am…

基于JavaWeb+SSM+Vue家庭记账本微信小程序系统的设计和实现

基于JavaWebSSMVue家庭记账本微信小程序系统的设计和实现 源码获取入口前言主要技术系统设计功能截图Lun文目录订阅经典源码专栏Java项目精品实战案例《500套》 源码获取 源码获取入口 前言 1.1选题背景 互联网是人类的基本需求&#xff0c;特别是在现代社会&#xff0c;个人…