前端新手Vue3+Vite+Ts+Pinia+Sass项目指北系列文章 —— 第十一章 基础界面开发 (组件封装和使用)

前言

Vue 是前端开发中非常常见的一种框架,它的易用性和灵活性使得它成为了很多开发者的首选。而在 Vue2 版本中,组件的开发也变得非常简单,但随着 Vue3 版本的发布,组件开发有了更多的特性和优化,为我们的业务开发带来了更多便利。本文将介绍如何使用 Vue3 开发业务组件,并通过代码实例进行演示。

一、自己封装组件

1、button 代码

src 目录下创建 components 文件夹,并在该文件夹下创建 Button 文件。
Button 文件中创建 index.vue 文件和 index.ts 文件,并编写以下代码
index.vue 文件中编写以下代码

<script lang="ts" setup name="ZButton">
defineProps({text: {type: String,default: ''},btnSize: {type: String,default: 'default'},size: {type: Number,default: 14},type: {type: String,default: 'default'},left: {type: Number,default: 0},right: {type: Number,default: 0},disabled: {type: Boolean,default: false},loading: {type: Boolean,default: false}
})
</script><template><div :type="type" :size="btnSize" :class="`z-button-${type}`" :disabled="disabled" :loading="loading" :style="{marginLeft: `${left}px`,marginRight: `${right}px`}">{{ text }}</div>
</template><style lang="scss" scoped>
.z-button-blue {background: #80d4fb;color: #fff;border: none;&:hover,&:focus,&:active {background: #80d4fb80;color: #fff;}.anticon {color: #fff;}
}.z-button-warn {background: #ec622b;color: #fff;border: none;outline: none;&:hover,&:focus,&:active {background-color: #ec622b80;color: #fff;}.anticon {color: #fff;}
}
</style>

index.ts 文件中编写以下代码

import ZButton from "./index.vue";export default ZButton

2、button 使用组件

我们在 home 页面导入组件来进行测试

<script setup lang="ts">
import { useRouter } from 'vue-router'
import useUserStore from '@/store/modules/user'
import ZButton from '@/components/Button/index' // 新增const router = useRouter()
const userStore = useUserStore()function goRouter(path: string): void {router.push(path)
}function getUserInfo(): void {console.log(userStore.userInfo, 'userStore.userInfo')
}
</script><template><div class="flex-c flex-align h-100"><el-button type="primary" @click="goRouter('/news')">go news</el-button><el-button type="primary" @click="goRouter('/user')">go user</el-button><el-button @click="getUserInfo">get user info</el-button><el-button type="primary" @click="goRouter('/table')">go table</el-button><!-- 新增 --><z-button type="blue" text="测试blue" :left="10"></z-button><!-- 新增 --><z-button type="warn" text="测试warn" :left="10"></z-button></div>
</template>

3、button 效果图

在这里插入图片描述

二、基于 Element-Plus 封装组件

1、table 代码

components 文件夹下创建 Table 文件。

Table 文件中创建 index.vueindex.tstypes.ts 文件,并编写以下代码
index.vue 文件中编写以下代码

<script setup lang="ts" name="ZTable">
import { ref, computed, watch, nextTick, defineExpose } from 'vue'
import { ElTable } from 'element-plus'
import { ZTableOptions } from './types'const props = withDefaults(defineProps<{// 表格配置选项propList: ZTableOptions[]// 表格数据data: any[]// 表格高度height?: string | numbermaxHeight?: string | number// 显示复选框showSelectColumn?: boolean// 显示复选框showExpand?: boolean// 显示序号showIndexColumn?: boolean// 显示操作columnoperation?: boolean// 操作column 宽度operationWidth?: stringmoreOperationsPopoverWidth?: string// 加载状态loading?: boolean// 加载文案loadingText?: string// 加载图标名elementLoadingSpinner?: string// 是否显示分页pagination?: boolean// 显示分页的对齐方式paginationAlign?: 'left' | 'center' | 'right'pageInfo?: any// 显示分页数据多少条的选项pageSizes?: number[]// 数据总条数total?: numberemptyImg?: boolean}>(),{propList: () => [],height: '100%',operation: true,operationWidth: '240px',moreOperationsPopoverWidth: '160px',paginationAlign: 'right',pageInfo: () => ({ page: 1, size: 10 }),pageSizes: () => [10, 15, 20, 30],total: 0,emptyImg: true}
)const ZTableRef = ref<InstanceType<typeof ElTable>>()
const tablePropList: any = ref([])watch(() => props.propList,(list) => {tablePropList.value = []nextTick(() => {tablePropList.value = JSON.parse(JSON.stringify(list))})},{immediate: true}
)// 表格分页的排列方式
const justifyContent = computed(() => {if (props.paginationAlign === 'left') return 'flex-start'else if (props.paginationAlign === 'right') return 'flex-end'else return 'center'
})const emits = defineEmits(['row-click','select-rows','page-change','sort-change','operation-click'
])const handleOperationClick = (row: any, code: string, index: number) => {emits('operation-click', code, row, index)
}
const selectable = (row: any, index: any) => {return !row.noSelectable
}
const handleRowClick = (row: any, column: any) => {if (column?.label == '操作') returnemits('row-click', row, column)
}
const handleSelectionChange = (list: any) => {emits('select-rows', list)
}
const handleSizeChange = (size: number) => {emits('page-change', { page: 1, size })
}
const handleCurrentChange = (page: number) => {emits('page-change', { ...props.pageInfo, page })
}
const changeTableSort = (value: any) => {emits('sort-change', value)
}
const toggleSelection = (rows?: any) => {if (rows) {rows.forEach((row: any) => {ZTableRef.value!.toggleRowSelection(row, true)})} else {ZTableRef.value!.clearSelection()}
}defineExpose({toggleSelection
})
</script><template><div class="z-table"><el-table :data="data" :height="height" :max-height="maxHeight" ref="ZTableRef" v-loading="loading":element-loading-text="loadingText" :element-loading-spinner="elementLoadingSpinner" stripe@sort-change="changeTableSort" @row-click="handleRowClick" @selection-change="handleSelectionChange"v-bind="$attrs"><template #empty v-if="emptyImg"><div class="empty-box"><el-empty></el-empty></div></template><el-table-column type="expand" v-if="showExpand"><template #default="scope"><slot name="baseExpandSlot" :row="scope.row"></slot></template></el-table-column><el-table-column v-if="showSelectColumn" type="selection" :selectable="selectable" fixed="left" align="center"width="55"></el-table-column><el-table-column v-if="showIndexColumn" fixed="left" type="index" label="序号" align="center"width="55"></el-table-column><template v-for="propItem in tablePropList" :key="propItem.prop"><template v-if="propItem.visible !== false"><template v-if="!propItem.slotName"><el-table-column v-bind="propItem"></el-table-column></template><template v-else><el-table-column v-bind="propItem"><template #default="scope"><slot :name="propItem.slotName" :format="propItem.dateFormat" :row="scope.row" :prop="propItem.prop":index="scope.$index"></slot></template></el-table-column></template></template></template><el-table-column v-if="operation" label="操作" :width="operationWidth" fixed="right"><template #default="scope"><template v-if="scope.row.operations"><div class="operations-wrap"><template v-for="(o, i) in scope.row.operations" :key="o.code"><el-button v-if="i < 3" text type="primary" size="small" :disabled="o.disabled"@click="handleOperationClick(scope.row, o.code, scope.$index)">{{ o.name }}</el-button></template><el-popover placement="bottom-end" :width="moreOperationsPopoverWidth"v-if="scope.row.operations.length > 3"><template #reference><el-icon color="#26A5FF" class="more-dot"><MoreFilled /></el-icon></template><div class="more-operations"><template v-for="(o, i) in scope.row.operations" :key="o.code"><el-button v-if="i > 2" text type="primary" size="small" :disabled="o.disabled" @click="handleOperationClick(scope.row, o.code, scope.$index)">{{ o.name }}</el-button></template></div></el-popover></div></template></template></el-table-column></el-table><div v-if="pagination" class="pagination" :style="{ justifyContent }"><el-pagination small :current-page="pageInfo.page" :page-sizes="pageSizes" :page-size="pageInfo.size"layout="total, sizes, prev, pager, next, jumper" :total="total" @size-change="handleSizeChange"@current-change="handleCurrentChange"></el-pagination></div></div>
</template><style lang="scss" scoped>
.operations-wrap {.el-button+.el-button {margin-left: 25px;}.more-dot {position: relative;top: 0.3em;margin-left: 25px;font-size: 20px;cursor: pointer;}
}.more-operations {display: flex;flex-wrap: wrap;.el-button {overflow: hidden;margin-left: 10px;height: 32px;border-radius: 8px;line-height: 32px;}
}.el-loading-mask {z-index: 1;
}.pagination {display: flex;margin-top: 16px;
}.el-table__expand-column .cell {width: 55px;
}.is-dark {max-width: 40%;
}
</style>

index.ts 文件中编写以下代码

import ZTable from './index.vue'export default ZTable

types.ts 文件中编写以下代码

export interface ZTableOptions {// 是否可见visible?: boolean// 自定义列模板的插槽名slotName?: string// 日期格式化dateFormat?: string// 表头label: string// 字段名称prop?: string// 对应列的宽度width?: string | numberminWidth?: string | number// 对齐方式align?: 'left' | 'center' | 'right'fixed?: true | 'left' | 'right'showOverflowTooltip?: booleansortable?: boolean | 'custom'
}

2、table 组件使用

table 文件中下添加 index.vue 并添加对应路由文件,编写以下代码

<script lang="ts" setup>
import ZTable from '@/components/Table/index'
import { ref } from 'vue'
import { ZTableOptions } from '@/components/Table/types'const tableData: any = ref([{fileName: '测试文件01',fileType: 'pdf',submitterName: '张三',submitTime: '2024-01-04 09:34:18'},{fileName: '测试文件02',fileType: 'png',submitterName: '李四',submitTime: '2024-01-04 11:26:57'}
])const propList: ZTableOptions[] = [{showOverflowTooltip: true,label: '文件名称',prop: 'fileName',minWidth: 130,align: 'left'},{showOverflowTooltip: true,label: '文件类型',prop: 'fileType',minWidth: 130,align: 'left'},{label: '上传人',prop: 'submitterName',minWidth: 150,showOverflowTooltip: true},{label: '上传时间',prop: 'submitTime',minWidth: 160}
]
</script><template><div><z-table :propList="propList" :data="tableData" :operation="false"></z-table></div>
</template><style scoped lang="scss">
</style>

3、table 效果图

在这里插入图片描述

总结

通过以上的介绍和代码实例,我们可以看到 Vue3 提供了更多的特性和优化,让我们更加方便地开发业务组件。在实际开发中,我们可以根据实际需求选择合适的组件开发方式,并通过 Vue3 的特性来提升开发效率。希望本文能够帮助到你在 Vue3 开发中的业务组件开发。上文中的配置代码可在 github 仓库中直接 copy,仓库路径:https://github.com/SmallTeddy/ProjectConstructionHub。

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

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

相关文章

有事休假店铺无人看守怎么办?智能远程视频监控系统保卫店铺安全

在春节期间&#xff0c;很多自营店主也得到了久违的假期&#xff0c;虽然很多店主都是长期在店铺中看守&#xff0c;但遇到春节这样的日子&#xff0c;多数人还是选择回乡休假。面对店主休假或有事不能管理店铺时&#xff0c;传统的监控虽然可以做到单一的监控&#xff0c;却仍…

用HTML Canvas和JavaScript创建美丽的花朵动画效果

目录 一、程序代码 二、代码原理 三、运行效果 一、程序代码 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>炫酷花朵</title><style>* {margin: 0;padding: 0;overflow: hidden;bac…

Windows 使设置更改立即生效——并行发送广播消息

目录 前言 1 遍历窗口句柄列表 2 使用 SendMessageTimeout 发送延时消息 3 并行发送消息实现模拟广播消息 4 修改 UIPI 消息过滤器设置 5 托盘图标刷新的处理 6 完整代码和测试 本文属于原创文章&#xff0c;转载请注明出处&#xff1a; https://blog.csdn.net/qq_5907…

不知如何获取1688工厂档案信息,你还在为此烦恼吗?

阿里巴巴集团旗下的B2B电子商务网站&#xff0c;提供海量优质商品&#xff0c;为采购商和供应商提供交流、合作、采购等服务&#xff0c;是很多没有货源优势的电商卖家首选的货源途径&#xff0c;也是国内最大、货源种类最齐全的货源网站。 不少做跨境电商无货源的朋友都想要1…

c# #if 与 Conditional属性宏的区别

测试代码 using System; using System.Diagnostics;namespace ConsoleApp1 {public class TestClass{[Conditional("Debug1")]public static void Func1(){Console.WriteLine("Conditional 宏");}public static void Func2(){ #if Debug2Console.WriteLin…

欠定方程组及其求解

欠定方程组是指方程的数量少于未知数的数量的方程组。在这种情况下&#xff0c;通常有无限多个解&#xff0c;因为给定的方程不足以唯一确定所有未知数的值。在某些情况下&#xff0c;我们可以利用额外的信息或假设&#xff0c;如稀疏性或其他约束&#xff0c;来找到一个合理的…

AT24C02(I2C总线)通信的学习

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、存储器介绍二、AT24C02芯片二、I2C总线I2C电路规范I2C时序结构I2C数据帧AT24C02数据帧 总结 前言 学习AT24C02(I2C总线)芯片 一、存储器介绍 RAM&#xf…

更改WordPress作者存档链接author和Slug插件Edit Author Slug

WordPress默认所有用户的存档永久链接都是/author/username/&#xff0c;不管是管理员还是订阅者或贡献者或作者或编辑。如果你想要自定义用户存档链接&#xff0c;比如根据角色不同使用不一样的author&#xff0c;或者自定义作者链接中的用户名Slug&#xff0c;那么建议考虑使…

解决kkFileView4.4.0版本pdf、word不能预览问题

这里使用的是http下载流url预览&#xff0c;遇到的问题。 官方使用指南&#xff1a;kkFileView - 在线文件预览 1 前端测试代码 1.1 官方示例代码 1.2 本人测试代码 注意&#xff1a;要给预览文件的url进行编码encodeURIComponent(Base64.encode(previewUrl))。 <!DOCTYP…

人工智能|机器学习——基于机器学习的舌苔检测

代码下载&#xff1a; 基于深度学习的舌苔检测毕设留档.zip资源-CSDN文库 1 研究背景 1.1.研究背景与意义 目前随着人们生活水平的不断提高&#xff0c;对于中医主张的理念越来越认可&#xff0c;对中医的需求也越来越多。在诊断中&#xff0c;中医通过观察人的舌头的舌质、苔…

Linix与Windows上使用nc命令测试某一个服务器端口网络是否正常可访问详细安装及测试步骤

一、windows 1、下载nc安装包 https://nszyf.lanzoum.com/ihtqS0v0lwwh 2、下载后解压放置在自己电脑合适的位置&#xff0c;并且配置到环境变量中 3、配置成功环境变量&#xff0c;winr打开运行&#xff0c;输入cmd&#xff0c;回车&#xff0c;打开一个终端测试 测试成功…

Kubernetes基础(二十二)-k8s持久化存储详解

1 volume 1.1 介绍 在容器中的磁盘文件是短暂的&#xff0c;当容器崩溃时&#xff0c;Kubelet会重新启动容器&#xff0c;但容器运行时产生的数据文件都将会丢失&#xff0c;之后容器会以最干净的状态启动。另外&#xff0c;当一个Pod运行多个容器时&#xff0c;各个容器可能…

Springboot+vue的疫情信息管理系统(有报告)。Javaee项目,springboot vue前后端分离项目。

演示视频&#xff1a; Springbootvue的疫情信息管理系统&#xff08;有报告&#xff09;。Javaee项目&#xff0c;springboot vue前后端分离项目。 项目介绍&#xff1a; 本文设计了一个基于Springbootvue的前后端分离的疫情信息管理系统&#xff0c;采用M&#xff08;model&a…

曲线生成 | 图解B样条曲线生成原理(基本概念与节点生成算法)

目录 0 专栏介绍1 什么是B样条曲线&#xff1f;2 基函数的de Boor递推式3 B样条曲线基本概念图解4 节点生成公式 0 专栏介绍 &#x1f525;附C/Python/Matlab全套代码&#x1f525;课程设计、毕业设计、创新竞赛必备&#xff01;详细介绍全局规划(图搜索、采样法、智能算法等)…

自动化上位机开发C#100例:如何用面向对象的方式封装雷赛运动控制卡EtherCAT总线卡(C#代码)

自动化上位机开发C#100例:雷赛运动控制卡EtherCAT总线卡C#封装类 文章目录 LTDMC.dll下载LTDMC.cs LTDMC.dll C#调用封装下载ICard.cs 运动控制卡接口Card.cs 运动控制卡抽象类CardLTDMC.cs 雷赛运动控制卡EtherCAT总线卡实现类CardList.cs 总线卡列表封装 LTDMC.dll下载 最新…

给label-studio 配置sam(segment anything)ml 记录

给label-studio 配置sam&#xff08;segment anything&#xff09;ml 后端记录 配置ml后台下载代码下载模型文件创建环境模型转换后端服务启动 配置label-studio 前端配置模型后端连接配置标注模板标注界面使用 参考链接 配置ml后台 下载代码 git clone https://github.com/H…

Web服务器基础

Web服务器基础 【一】前端概述 【1】HTML HTML&#xff08;超文本标记语言&#xff09;是用于创建网页结构的标记语言。它定义了网页的骨架&#xff0c;包括标题、段落、列表、链接等元素&#xff0c;但没有样式。可以将HTML视为网页的结构和内容的描述。 【2】CSS css&…

mac安装python

1、官网下载安装包&#xff1a; https://www.python.org/downloads/macos/ 2、运行安装包&#xff1a; 3、验证

【conda环境 安装 tensorflow2.2】 解决方案

1.检查anaconda安装&#xff1a;在cmd输入 conda --version 2.检测已经安装的环境&#xff1a;conda info --envs 3.新建一个python3.5的环境&#xff0c;tensorflow&#xff1a; ###conda create -n xxx python3.5 xxx为虚拟环境名 ###conda create -n xxx python3.6 xxx为虚拟…

office的excel中使用,告诉我详细的解决方案,如何变成转化为金额格式

在Office的Excel中&#xff0c;如果你想将名为"MEREFIELD"的公式结果转换为金额格式&#xff0c;你可以遵循以下详细步骤来实现&#xff1a; 书写MEREFIELD公式&#xff1a; 首先&#xff0c;在Excel中输入或确认你的MEREFIELD公式。例如&#xff0c;假设这个公式是用…