Day57:组件库封装-1

news/2025/2/12 15:19:25/

封装element组件

参考对象 折叠面板 按钮

npm create vue@3

npm i

使用vue3建库如果报错可以尝试禁用vs的 vetur 插件,这是vue2插件,会给vue3项目报错(禁用了之后需要重新加载

src新建components文件夹

下面新建Button文件夹,新建vue,ts,css文件

使用postcss书写样式

在APP引入script setup lang=ts

引入自定义前缀button并在appvue视图中实现

<template><div><!-- 组件库中的Button是通过接受一系列的props来添加不同的类名然后给这些类名添加不同的样式 --><!-- 实现type=primary 这样一个蓝色的button --><xzd-button type="primary">primary按钮</xzd-button><xzd-button type="danger">danger按钮</xzd-button><xzd-button type="danger" disabled>禁用按钮</xzd-button><xzd-button type="info" circle>圆</xzd-button><xzd-button type="danger" round>圆角按钮</xzd-button><xzd-button size="large">大按钮</xzd-button><xzd-button size="small">小按钮</xzd-button></div>
</template>
<script setup lang="ts">
import XzdButton from './components/Button/XzdButton.vue'
</script>

给button不仅要添加自定义type,也要添加原生的type

组建库中的button是通过接受一系列的props来添加不同的类名

引入组件前缀button从前缀button.vue

传递一个type=primary的蓝色圆角button效果

公共button类

约定每个类的可选类型

把可选类型进一步拆分

把类型传递出去

import type { PropType } from "vue";
export type ButtonType = 'primary' | 'success' | 'waring' |'info' | 'danger'
export type ButtonSize = 'large' | 'small'
export type nativeType = 'button' | 'reset' | 'submit'export interface ButtonProps {type?: ButtonType;size?: ButtonSize;plain?: boolean;round?: boolean;circle?: boolean;disabled?: boolean;nativeType?: nativeType;autofocus?: boolean//还需要接受2个原生的button属性
}
//props的类型如果封装成一个单独的文件 在引入的时候无法正确编译
export const buttonprops = {type: {type: String as PropType<ButtonType>,required: false},size: {type: String as PropType<ButtonSize>,required: false},plain: {type: Boolean,required: false},round: {type: Boolean,required: false},circle: {type: Boolean,required: false},disabled: {type: Boolean,required: false},nativeType: {type: String as PropType<nativeType>,required: false},autofocus: {type: Boolean,required: false}
}

自己定义的类名前缀button中用模板字符串拼接输入的type

判断是否为朴素类型,圆角,圆形

再加一个:disabled=disabled

在app中给button书写需要的可选类名

给文本内容分配插槽

在src下新建文件夹styles,新建vars.css和index.css。

由于没有设计

在把vars.css中element的系列颜色在检查元素的时候右键全部复制粘贴进来

统一替换el为自己定义的类名前缀

除了color之外还有border、font、相关的

reset.css清除浏览器默认样式。新建文件,并引入到index.css中

/* 定义一批css变量 */
@import './vars.css';
@import './reset.css';

想在css中实现嵌套,安装postcss即可,

新建postcss.config.cjs

npm i postcss-nested -D

安装vs高亮插件

在button的css中定义button的相关样式,并将button的css引入到styles中的index.css

通过type可以决定按钮的样式

在button的css中为button添加间距

选中button需要有focus、hover效果。边框active时变深

.xzd-button {& + & {margin: 12px;}&:hover,&:focus {color: var(--xzd-button-text-color);border-color: var(--xzd-button-hover-border-color);}&:active {color: var(--xzd-button-text-color);border-color: var(--xzd-button-active-border-color);}
}

修改朴素按钮的hover效果 &.is-plain ,&.is-round圆角,&.is-circle圆形

禁用按钮需要用原生的cursor: not-allowed;的禁用。需要给类名和属性,还有类名和属性的hover和focus也添加禁用。

.xzd-button {/* disabled */&.is-disabled,&.is-disabled:hover,&.is-disabled:focus,&[disabled],&[disabled]:hover,&[disabled]:focus {color: var(--xzd-button-disabled-text-color);cursor: not-allowed;background-image: none;background-color: var(--xzd-button-disabled-bg-color);border-color: var(--xzd-button-disabled-border-color);}
}

设置large和small对应尺寸的样式,并在buttonvue中添加[`xzd-button--${size}`]: size,

.xzd-button--large {--xzd-button-size: 40px;height: var(--xzd-button-size);padding: 12px 19px;font-size: var(--xzd-font-size-base);border-radius: var(--xzd-border-radius-base);
}
.xzd-button--small {--xzd-button-size: 24px;height: var(--xzd-button-size);padding: 5px 11px;font-size: 12px;border-radius: calc(var(--xzd-border-radius-base) - 1px);
}

设置产品系列颜色,使用遍历的方法写。在postcss中,想要支持写遍历,需要安装npm i postcss-each -D

给primary, success, warning, info, danger做一个遍历。 $val相当于循环变量,每次遍历的时候会替换成五个中的一个。遍历到哪个就给他添加一个新的值

/* 给不同的type类型添加上对应的样式(产品色彩) */
@each $val in primary, success, warning, info, danger {.xzd-button--$(val) {--xzd-button-text-color: var(--xzd-color-white);--xzd-button-bg-color: var(--xzd-color-$(val));--xzd-button-border-color: var(--xzd-color-$(val));--xzd-button-outline-color: var(--xzd-color-$(val)-light-5);--xzd-button-active-color: var(--xzd-color-$(val)-dark-2);--xzd-button-hover-text-color: var(--xzd-color-white);--xzd-button-hover-bg-color: var(--xzd-color-$(val)-light-3);--xzd-button-hover-border-color: var(--xzd-color-$(val)-light-3);--xzd-button-active-bg-color: var(--xzd-color-$(val)-dark-2);--xzd-button-active-border-color: var(--xzd-color-$(val)-dark-2);--xzd-button-disabled-text-color: var(--xzd-color-white);--xzd-button-disabled-bg-color: var(--xzd-color-$(val)-light-5);--xzd-button-disabled-border-color: var(--xzd-color-$(val)-light-5);}

primary的按钮不是朴素按钮,hover时有一层白色遮罩,需要单独处理。但每一样单独处理非常麻烦,需要在css中使用遍历

@each $val in primary, success, warning, info, danger {.xzd-button--$(val) {...}.xzd-button--$(val).is-plain {--xzd-button-text-color: var(--xzd-color-$(val));--xzd-button-bg-color: var(--xzd-color-$(val)-light-9);--xzd-button-border-color: var(--xzd-color-$(val)-light-5);--xzd-button-hover-text-color: var(--xzd-color-white);--xzd-button-hover-bg-color: var(--xzd-color-$(val));--xzd-button-hover-border-color: var(--xzd-color-$(val));--xzd-button-active-text-color: var(--xzd-color-white);}
}

注:sass原生支持嵌套和变量,和遍历

/* 给不同的type类型添加上对应的样式(产品色彩) */
@each $var in primary,success,warning,info,danger{.xzd-button--$(var) {--xzd-button-bg-color: var(--xzd-color-$(var));}
}

在前缀buttonvue中传一个默认值在网页检查端

折叠面板封装

新建文件夹,在app中引入

<xzd-collapse><xzd-collapse-item name='1' title='标题1' disabled> <!-- 无法展开 --><div>第一个折叠面板的内容</div></xzd-collapse-item></xzd-collapse>

必须要有name属性,添加title属性

新建两个vue——xzd-collapse和xzd-collapse-item

xzd-collapse中只写类名和插槽<solt />

xzd-collapse-item中写类名

在类型ts中,name是必传的,所以单独封装类型

余下的在export interface CollapseItemProps中规定传参类型

import type { InjectionKey } from "vue"export type PropsName = string | number
export interface CollapseItemProps {name:PropsName,title?:string,disable?:boolean
}

基础用法写法

手风琴效果:每次只能展开一个面板。

通过accordion属性来设置是否以手风琴模式显示

基础写法:可以展开多个面板,面板之间互不影响

在item.vue上写头部样式(div)

在xzd-collapse-item中引入规定好的CollapseItemProps泛型参数

import type { CollapseItemProps } from './type'
defineProps<CollapseItemProps>()

在视图中写动态接受的div{{title}},给title写样式,样式中有一项为id,id中模板字符串为动态唯一值name

标题下面写内容,给内容书写样式,也动态唯一值name

只要传递过来disabled类名,则禁止点击

<div class="xzd-collaspe-item"><div class="xzd-collaspe-item__header" :class="{'is-disabled': disabled}" :id="`xzd-collaspe-head-${name}`">{{ title }}</div><div class="xzd-clooapse-item__wrapper" :id="`xzd-collaspe-wrapper-${name}`"><div class="xzd-clooapse-item__content"></div></div>
</div>

在app中引入两个Collapse,以显示Collapse标签的内容

在item.vue中引入type.ts中定义好的props约束,来约束数据类型

itemvue的title不能直接写为{{}},需要写在传递的插槽里。在app中以具名插槽的形式给插槽title传递title

<div class="xzd-collaspe-item__header" 
:class="{'is-disabled': disabled
}" 
:id="`xzd-collaspe-head-${name}`"><slot name="title">{{ title }}</slot>
</div>

div中以具名插槽的形式传递title的内容

在Collapse中定义activeName,为空数组,如果点击哪一项,就给中间传哪一项的name。且给activeName传了约束类型PropsName数组型

需要传递一个点击事件,在点击折叠面板头部的时候触发, 点击后在activeName如果有这一项,就删除这一项,如果没有就添加上这一项

给子组件传递activeName,需要在collaspe-item内部做判断,判断这个数组中是否包含当前的name值。如果在,当前折叠面板应该展开,否则闭合

import {ref} from 'vue'
import type {PropsName} from './'
let activeName = ref<PropsName[]>([])
let handleClick = (name: PropsName): void => {// 判断这个数组中是否包含当前的name值。在,当前折叠面板应该展开,否则闭合const index = activeNames.value.indexOf(name) // 只要不存在就是-1,存在为具体值if(index > -1) {activeNames.value.splice(index,1) /* 删除 */}else{activeNames.value.push(name) /* 加上 */}
}

跨级且使用插槽不能用props传参,需要使用依赖注入传递参数。

跨级传递,需要给传参一个唯一的key值

在type.ts中export一下collapseContextKey,再引入回item

在CollapseContext中规定要传递的参数的类型,再使用symbol生成唯一的collapseContextKey

从父组件中传参到子组件item

通过inject collapseContextKey来得到父子组件之间的传值

通过isActive的变量来判断当前Item的name是否存在于activeNames中。如果在显示对应的content,否则不显示。

定义一个isActive,通过computed来判断是否为真。在视图中v-show isActive,为真显示,为假不显示。

在item.vue头部定义点击事件handleClick,再实现一下handleClick方法。

点击标题的头部,如果它在显示,让那一条折叠面板收起来;如果没显示,则显示。

如果disable,则直接return

组间传递的方法handleClick和点击的那个头的name


http://www.ppmy.cn/news/1125949.html

相关文章

Zookeeper高级_选举机制

核心选举原则 Zookeeper集群中只有超过半数以上的服务器启动&#xff0c;集群才能正常工作&#xff1b;在集群正常工作之前&#xff0c;myid小的服务器给myid大的服务器投票&#xff0c;直到集群正常工作&#xff0c;选出Leader&#xff1b;半数机制&#xff1b; 选举机制流程…

ps 去除图标背景色

百度安全验证 https://baijiahao.baidu.com/s?id1766678909759797922&wfrspider&forpc 使用魔术橡皮擦工具&#xff0c;超级简单 最后&#xff0c;保存为PNG格式&#xff0c;因为PNG格式支持透明背景。

从裸机开始安装操作系统

目录 一、预置知识 电脑裸机 win10版本 官方镜像 V.S. 正版系统 二、下载微软官方原版系统镜像 三、使用微PE系统维护U盘 四、安装操作系统 五、总结 一、预置知识 电脑裸机 ●只有硬件部分&#xff0c;还未安装任何软件系统的电脑叫做裸机。 ●主板、硬盘、显卡等必…

利用EXCEL进行XXE攻击

利用EXCEL进行XXE攻击 原因 原因 Microsoft Office从2007版本引入了新的开放的XML文件格式&#xff0c;新的XML文件格式基于压缩的ZIP文件格式规范&#xff0c;由许多部分组成。 我们可以将其解压缩到特定的文件夹中来查看其包含的文件夹和文件&#xff0c;可以发现其中多数是…

上传文件报错:The temporary upload location [/tmp/tomcat/xxx] is not valid

1.上传附加时报错找不到临时目录 Failed to parse multipart servlet request; nested exception is java.io.IOException: The temporary upload location [/tmp/tomcat/work/Tomcat/localhost/ROOT] is not valid 发生改报错原因为 (1)、SpringBoot项目启动后&#xff0c;系…

Mybatisplus条件构造器

一、Wrapper介绍 Wrapper &#xff1a; 条件构造抽象类&#xff0c;最顶端父类 AbstractWrapper &#xff1a; 用于查询条件封装&#xff0c;生成 sql 的 where 条件 QueryWrapper &#xff1a; 查询条件封装UpdateWrapper &#xff1a; Update 条件封装AbstractLambdaWrapper…

MQ - 31 基础功能: 优先级队列的设计

文章目录 导图概述什么是优先级队列如何设计实现优先级队列业务实现优先级队列的效果内核支持优先级队列RabbitMQ 中优先级队列的实现总结导图 概述 当我们需要在业务中对消息设置优先级,让优先级高的消息能被优先消费,此时就需要用到消息队列中优先级队列的特性。 为了了解…

快速使用Spring Cache

哈喽~大家好&#xff0c;这篇我们来看看快速使用Spring Cache。 &#x1f947;个人主页&#xff1a;个人主页​​​​​ &#x1f948; 系列专栏&#xff1a;【日常学习上的分享】 &#x1f949;与这篇相关的文章&#xff1a; R…