当前位置: 首页 > news >正文

用Vue3.0 写过组件吗?如果想实现一个 Modal你会怎么设计?

一、组件设计

组件就是把图形、非图形的各种逻辑均抽象为一个统一的概念(组件)来实现开发的模式

现在有一个场景,点击新增与编辑都弹框出来进行填写,功能上大同小异,可能只是标题内容或者是显示的主体内容稍微不同

这时候就没必要写两个组件,只需要根据传入的参数不同,组件显示不同内容即可

这样,下次开发相同界面程序时就可以写更少的代码,意义着更高的开发效率,更少的 Bug 和更少的程序体积

二、需求分析

实现一个Modal组件,首先确定需要完成的内容:

  • 遮罩层
  • 标题内容
  • 主体内容
  • 确定和取消按钮

主体内容需要灵活,所以可以是字符串,也可以是一段 html 代码

特点是它们在当前vue实例之外独立存在,通常挂载于body之上

除了通过引入import的形式,我们还可通过API的形式进行组件的调用

还可以包括配置全局样式、国际化、与typeScript结合

三、实现流程

首先看看大致流程:

  • 目录结构
  • 组件内容
  • 实现 API 形式
  • 事件处理
  • 其他完善

目录结构

Modal组件相关的目录结构

├── plugins
│   └── modal
│       ├── Content.tsx // 维护 Modal 的内容,用于 h 函数和 jsx 语法
│       ├── Modal.vue // 基础组件
│       ├── config.ts // 全局默认配置
│       ├── index.ts // 入口
│       ├── locale // 国际化相关
│       │   ├── index.ts
│       │   └── lang
│       │       ├── en-US.ts
│       │       ├── zh-CN.ts
│       │       └── zh-TW.ts
│       └── modal.type.ts // ts类型声明相关

因为 Modal 会被 app.use(Modal) 调用作为一个插件,所以都放在plugins目录下

组件内容

首先实现modal.vue的主体显示内容大致如下

<Teleport to="body" :disabled="!isTeleport"><div v-if="modelValue" class="modal"><divclass="mask":style="style"@click="maskClose && !loading && handleCancel()"></div><div class="modal__main"><div class="modal__title line line--b"><span>{{ title || t("r.title") }}</span><spanv-if="close":title="t('r.close')"class="close"@click="!loading && handleCancel()">✕</span></div><div class="modal__content"><Content v-if="typeof content === 'function'" :render="content" /><slot v-else>{{ content }}</slot></div><div class="modal__btns line line--t"><button :disabled="loading" @click="handleConfirm"><span class="loading" v-if="loading"> ❍ </span>{{ t("r.confirm") }}</button><button @click="!loading && handleCancel()">{{ t("r.cancel") }}</button></div></div></div>
</Teleport>

最外层上通过Vue3 Teleport 内置组件进行包裹,其相当于传送门,将里面的内容传送至body之上

并且从DOM结构上来看,把modal该有的内容(遮罩层、标题、内容、底部按钮)都实现了

关于主体内容

<div class="modal__content"><Content v-if="typeof content==='function'":render="content" /><slot v-else>{{content}}</slot>
</div>

可以看到根据传入content的类型不同,对应显示不同得到内容

最常见的则是通过调用字符串和默认插槽的形式

// 默认插槽
<Modal v-model="show"title="演示 slot"><div>hello world~</div>
</Modal>// 字符串
<Modal v-model="show"title="演示 content"content="hello world~" />

通过 API 形式调用Modal组件的时候,content可以使用下面两种

  • h 函数
$modal.show({title: '演示 h 函数',content(h) {return h('div',{style: 'color:red;',onClick: ($event: Event) => console.log('clicked', $event.target)},'hello world ~');}
});
  • JSX
$modal.show({title: '演示 jsx 语法',content() {return (<divonClick={($event: Event) => console.log('clicked', $event.target)}>hello world ~</div>);}
});

实现 API 形式

那么组件如何实现API形式调用Modal组件呢?

Vue2中,我们可以借助Vue实例以及Vue.extend的方式获得组件实例,然后挂载到body

import Modal from './Modal.vue';
const ComponentClass = Vue.extend(Modal);
const instance = new ComponentClass({ el: document.createElement("div") });
document.body.appendChild(instance.$el);

虽然Vue3移除了Vue.extend方法,但可以通过createVNode实现

import Modal from './Modal.vue';
const container = document.createElement('div');
const vnode = createVNode(Modal);
render(vnode, container);
const instance = vnode.component;
document.body.appendChild(container);

Vue2中,可以通过this的形式调用全局 API

export default {install(vue) {vue.prototype.$create = create}
}

而在 Vue3 的 setup 中已经没有 this 概念了,需要调用app.config.globalProperties挂载到全局

export default {install(app) {app.config.globalProperties.$create = create}
}

事件处理

下面再看看看Modal组件内部是如何处理「确定」「取消」事件的,既然是Vue3,当然采用Compositon API 形式

// Modal.vue
setup(props, ctx) {let instance = getCurrentInstance(); // 获得当前组件实例onBeforeMount(() => {instance._hub = {'on-cancel': () => {},'on-confirm': () => {}};});const handleConfirm = () => {ctx.emit('on-confirm');instance._hub['on-confirm']();};const handleCancel = () => {ctx.emit('on-cancel');ctx.emit('update:modelValue', false);instance._hub['on-cancel']();};return {handleConfirm,handleCancel};
}

在上面代码中,可以看得到除了使用传统emit的形式使父组件监听,还可通过_hub属性中添加 on-cancelon-confirm方法实现在API中进行监听

app.config.globalProperties.$modal = {show({}) {/* 监听 确定、取消 事件 */}
}

下面再来目睹下_hub是如何实现

// index.ts
app.config.globalProperties.$modal = {show({/* 其他选项 */onConfirm,onCancel}) {/* ... */const { props, _hub } = instance;const _closeModal = () => {props.modelValue = false;container.parentNode!.removeChild(container);};// 往 _hub 新增事件的具体实现Object.assign(_hub, {async 'on-confirm'() {if (onConfirm) {const fn = onConfirm();// 当方法返回为 Promiseif (fn && fn.then) {try {props.loading = true;await fn;props.loading = false;_closeModal();} catch (err) {// 发生错误时,不关闭弹框console.error(err);props.loading = false;}} else {_closeModal();}} else {_closeModal();}},'on-cancel'() {onCancel && onCancel();_closeModal();}});
}
};

其他完善

关于组件实现国际化、与typsScript结合,大家可以根据自身情况在此基础上进行更改

参考文献

  • https://segmentfault.com/a/1190000038928664

相关文章:

用Vue3.0 写过组件吗?如果想实现一个 Modal你会怎么设计?

一、组件设计 组件就是把图形、非图形的各种逻辑均抽象为一个统一的概念&#xff08;组件&#xff09;来实现开发的模式 现在有一个场景&#xff0c;点击新增与编辑都弹框出来进行填写&#xff0c;功能上大同小异&#xff0c;可能只是标题内容或者是显示的主体内容稍微不同 …...

ArmSoM-W3之RK3588硬编解码MPP环境配置

1. 简介 瑞芯微提供的媒体处理软件平台&#xff08;Media Process Platform&#xff0c;简称 MPP&#xff09;是适用于瑞芯微芯片系列的 通用媒体处理软件平台。该平台对应用软件屏蔽了芯片相关的复杂底层处理&#xff0c;其目的是为了屏蔽不 同芯片的差异&#xff0c;为使用者…...

源码解析flink文件连接源TextInputFormat

背景&#xff1a; kafka的文件系统数据源可以支持精准一次的一致性,本文就从源码看下如何TextInputFormat如何支持状态的精准一致性 TextInputFormat源码解析 首先flink会把输入的文件进行切分&#xff0c;分成多个数据块的形式&#xff0c;每个数据源算子任务会被分配以读取…...

SQL ORDER BY Keyword(按关键字排序)

SQL ORDER BY 关键字 ORDER BY 关键字用于按升序或降序对结果集进行排序。 ORDER BY 关键字默认情况下按升序排序记录。 如果需要按降序对记录进行排序&#xff0c;可以使用DESC关键字。 SQL ORDER BY 语法 SELECT column1, column2, ... FROM table_name ORDER BY column1, …...

光伏三相并网逆变器的控制策略与性能分析(Simulink仿真实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…...

【网络安全 --- xss-labs靶场】xss-labs靶场安装详细教程,让你巩固对xss漏洞的理解及绕过技巧和方法(提供资源)

一&#xff0c;资源下载准备 1-1 VMware 16.0 安装请参考以下博客&#xff0c;若已经安装请忽略&#xff1a; 【网络安全 --- 工具安装】VMware 16.0 详细安装过程&#xff08;提供资源&#xff09;-CSDN博客【网络安全 --- 工具安装】VMware 16.0 详细安装过程&#xff08;…...

蓝桥每日一题(day 3: 蓝桥587.约数个数)--数学--easy

题目 解题核心&#xff1a; 分解质因数&#xff0c;每个质因数的次方1的累乘积就是anscode #include <iostream> #include<algorithm> #include<unordered_map> //# #include<> typedef long long LL; const int N 110, MOD 1e9 7;using namespac…...

深入剖析Java类加载过程:探寻类加载器的奥秘

摘要: 一个java文件从被加载到被卸载这个生命过程&#xff0c;总共要经历4个阶段&#xff1a; 加载->链接&#xff08;验证准备解析&#xff09;->初始化&#xff08;使用前的准备&#xff09;->使用->卸载 其中类加载过程包括加载、验证、准备、解析和初始化五个阶…...

PHP yield

概念&#xff1a; Generator&#xff1a;带 yield的function yield&#xff1a;Generator或task的中断关键字&#xff0c;执行到yield时一次调度周期执行完即阻塞&#xff0c;并返回右侧表达式结果&#xff0c;等待下一次调度器运行next()或迭代遍历才会继续往下执行&#xff0…...

react antd实现upload上传文件前form校验,同时请求带data

最近的需求&#xff0c;两个下拉框是必填项&#xff0c;点击上传按钮&#xff0c;如果有下拉框没选要有提示&#xff0c;如图 如果直接使用antd的Upload组件&#xff0c;一点击文件选择的窗口就打开了&#xff0c;哪怕在Button里再加点击事件&#xff0c;也只是&#xff08;几乎…...

echars 设置滚动条演示,

dataZoom: [// 滑动条{zoomLock:true,xAxisIndex: 0, // 这里是从X轴的0刻度开始type: "slider", // 这个 dataZoom 组件是 slider 型 dataZoom 组件startValue: 0, // 从头开始。endValue: 20, // 一次性展示几个。// fillerColor: "#023661", // 选中范围…...

代码随想录算法训练营第五十八天|583.两个字符串的删除操作 、72. 编辑距离

代码随想录算法训练营第五十八天|583.两个字符串的删除操作 、72. 编辑距离 文章目录 代码随想录算法训练营第五十八天|583.两个字符串的删除操作 、72. 编辑距离[toc]583.两个字符串的删除操作求公共部分长度&#xff1a;即最长公共子串 72. 编辑距离 583.两个字符串的删除操作…...

1024网络技术命令汇总(第54课)

1024网络技术命令汇总(第54课) 1 查询命令 display ? display current-configuration //查看全部的配置信息 display interface brief //查看接口的信 display ip interface brief //查看IP地址的接口信息状态 display arp all …...

智慧河湖方案:AI赋能水利水务,构建河湖智能可视化监管大数据平台

一、方案背景 我国江河湖泊众多&#xff0c;水系发达。伴随着经济社会快速发展&#xff0c;水生态水环境问题成为群众最关注的民生议题之一。一些河流开发利用已接近甚至超出水环境承载能力&#xff0c;一些地区废污水排放量居高不下&#xff0c;一些地方侵占河道、围垦湖泊等…...

界面组件DevExpress WPF v23.1 - 全面升级文档处理功能

DevExpress WPF拥有120个控件和库&#xff0c;将帮助您交付满足甚至超出企业需求的高性能业务应用程序。通过DevExpress WPF能创建有着强大互动功能的XAML基础应用程序&#xff0c;这些应用程序专注于当代客户的需求和构建未来新一代支持触摸的解决方案。 无论是Office办公软件…...

【C语言必知必会 | 第八篇】一文带你精通循环结构

引言 C语言是一门面向过程的、抽象化的通用程序设计语言&#xff0c;广泛应用于底层开发。它在编程语言中具有举足轻重的地位。 此文为【C语言必知必会】系列第八篇&#xff0c;进行C语言循环结构的专项练习&#xff0c;结合专题优质题目&#xff0c;带领读者从0开始&#xff0…...

同一个线程池执行不同类型的任务

1、同一个线程池可以执行不同的任务类型&#xff0c;也可以带返回值&#xff0c;也可以不带返回值的 import com.google.common.util.concurrent.ThreadFactoryBuilder; import com.vip.vman.result.BasicResult; import lombok.extern.slf4j.Slf4j; import org.springframewor…...

GEO生信数据挖掘(八)富集分析(GO 、KEGG、 GSEA 打包带走)

第六节&#xff0c;我们使用结核病基因数据&#xff0c;做了一个数据预处理的实操案例。例子中结核类型&#xff0c;包括结核&#xff0c;潜隐进展&#xff0c;对照和潜隐&#xff0c;四个类别。第七节延续上个数据&#xff0c;进行了差异分析。 本节对差异基因进行富集分析。 …...

高校教务系统登录页面JS分析——华南理工大学

高校教务系统密码加密逻辑及JS逆向 本文将介绍高校教务系统的密码加密逻辑以及使用JavaScript进行逆向分析的过程。通过本文&#xff0c;你将了解到密码加密的基本概念、常用加密算法以及如何通过逆向分析来破解密码。 本文仅供交流学习&#xff0c;勿用于非法用途。 一、密码加…...

人工智能之PyTorch数据操作-Python版

PyTorch数据操作 # 导入PyTorch import torch [张量表示一个由数值组成的数组&#xff0c;这个数组可能有多个维度]。 具有一个轴的张量对应数学上的向量&#xff08;&#xff09;&#xff1b; 具有两个轴的张量对应数学上的矩阵&#xff08;matrix&#xff09;&#xff1b;…...

3秒破解百度网盘提取码:智能查询工具如何彻底改变你的资源获取体验

3秒破解百度网盘提取码&#xff1a;智能查询工具如何彻底改变你的资源获取体验 【免费下载链接】baidupankey 项目地址: https://gitcode.com/gh_mirrors/ba/baidupankey 你是否曾因找不到百度网盘提取码而错失重要资源&#xff1f;面对海量学习资料却卡在"请输入…...

行政区划变更(撤县设市、撤县设区、省直管县、新设地级市)数据1993-2023年

01、数据介绍撤县设市是撤销县&#xff0c;设立县级市&#xff0c;行政制度与县级相同&#xff0c;将县改为县级市。地级市管辖的县撤县设市后&#xff0c;一般有省级直辖管理&#xff0c;为省直管市&#xff0c;实际仍由地级市代管。2022年《政府工作报告》中国务院提出&#…...

3大实战指南:G-Helper华硕笔记本性能优化深度解析

3大实战指南&#xff1a;G-Helper华硕笔记本性能优化深度解析 【免费下载链接】g-helper Lightweight, open-source control tool for ASUS laptops and ROG Ally. Manage performance modes, fans, GPU, battery, and RGB lighting across Zephyrus, Flow, TUF, Strix, Scar, …...

CREST分子构象搜索工具完整指南:从零开始掌握高效采样技术

CREST分子构象搜索工具完整指南&#xff1a;从零开始掌握高效采样技术 【免费下载链接】crest CREST - A program for the automated exploration of low-energy molecular chemical space. 项目地址: https://gitcode.com/gh_mirrors/crest/crest CREST&#xff08;Con…...

大模型的探索与实践-课程笔记(十一):大模型发展史与全球厂商业态全景

第一部分&#xff1a;从 NLP 到 Transformer 的底层架构演进早期的自然语言处理&#xff08;NLP&#xff09;主要依赖特征提取&#xff0c;大模型的基石是 Google 提出的架构革命。1. Transformer 与注意力机制 (2017年)起源&#xff1a;Google 2017年发表神作《Attention is a…...

EdgeChains:基于Java响应式编程构建生产级大语言模型应用框架

1. 项目概述&#xff1a;当大模型需要“记忆”与“逻辑”如果你最近在折腾大语言模型&#xff08;LLM&#xff09;的应用&#xff0c;比如想做个智能客服、文档问答或者知识库助手&#xff0c;大概率会遇到一个核心瓶颈&#xff1a;LLM本身是个“健忘症患者”&#xff0c;它无法…...

Matplotlib 柱形图:老板,这柱不是我画的,是数据自己长的

Matplotlib 柱形图柱形图&#xff08;Bar Chart&#xff09; 是一种用矩形柱子的高度&#xff08;或长度&#xff09;来表示数据大小的统计图表&#xff0c;是数据可视化中最基础、最常用的图表类型之一。在 Matplotlib 中&#xff0c;柱形图主要通过两个函数实现&#xff1a;函…...

云原生智能流量代理trae-agent:动态路由、负载均衡与熔断限流实战

1. 项目概述&#xff1a;一个面向云原生时代的智能流量代理最近在梳理团队内部的微服务治理工具链时&#xff0c;又仔细研究了一下bytedance/trae-agent这个项目。它不是一个简单的反向代理&#xff0c;而是一个设计理念相当超前的“智能流量代理”。简单来说&#xff0c;它就像…...

3D打印Cherry MX键帽:从设计到制造的完整开源方案

3D打印Cherry MX键帽&#xff1a;从设计到制造的完整开源方案 【免费下载链接】cherry-mx-keycaps 3D models of Chery MX keycaps 项目地址: https://gitcode.com/gh_mirrors/ch/cherry-mx-keycaps 你是否曾经为找不到特殊尺寸的键帽而烦恼&#xff1f;或者想为自己的机…...

为什么92%的MCP插件项目在生产环境崩溃?——基于GitHub 417个开源仓库的代码审计与性能基线对比报告

更多请点击&#xff1a; https://intelliparadigm.com 第一章&#xff1a;为什么92%的MCP插件项目在生产环境崩溃&#xff1f;——基于GitHub 417个开源仓库的代码审计与性能基线对比报告 核心失效模式&#xff1a;未声明的依赖生命周期冲突 审计发现&#xff0c;83.6% 的崩溃…...