Initial commit

This commit is contained in:
tanxin
2026-10-29 10:08:39 +08:00
commit 4c6243a274
124 changed files with 17359 additions and 0 deletions
+6
View File
@@ -0,0 +1,6 @@
## 1.0.2(2026-05-18)
- 修复类名拼写错误
## 1.0.1(2026-04-30)
- 更新文档
## 1.0.0(2026-04-30)
- 支持 uni-badge-view 组件
@@ -0,0 +1,287 @@
<template>
<!-- 如果不显示badge,则不包裹,直接显示子内容。保证常态下的高性能。但如果设置了alwaysWrapWithContent且有slot内容,则仍然保持包裹层 -->
<slot v-if="text == '0' && alwaysWrapWithContent== false"></slot>
<!-- 如果有多个子slot,且不设badge,去掉包裹层直接露出slot,会导致flex方向错乱。此时应设置alwaysWrapWithContent为true,总是保留包裹层 -->
<!-- 微信小程序不支持外部绑定事件 -->
<template v-else>
<view v-if="hasDefaultSlot" style="overflow: visible;" class="badge-wrap" v-bind="$attrs">
<!-- 目标内容插槽 -->
<slot></slot>
<!-- badge 文字模式 -->
<text v-if="text != '' && text != '0' " :class="['text', 'position', badgeClass]" :style="badgeStyle">
{{ text }}
</text>
<!-- badge 红点模式 -->
<view v-else-if="text != '0'" :class="['dot', 'position', badgeClass]" :style="badgeStyle"></view>
</view>
<!-- 不包裹,直接显示badge 文字模式 -->
<text v-else-if="text != ''" :class="['text', badgeClass]" :style="badgeStyle">
{{ text }}
</text>
<!-- 不包裹,直接显示badge 红点模式 -->
<view v-else :class="['dot', badgeClass]" :style="badgeStyle"></view>
</template>
</template>
<script setup lang="ts">
/**
* Badge 数字角标
* @description 数字角标(徽章)组件
* @uniPlatform {
* "app": {
* "android": {
* "uniVer": "x",
* "unixVer": "5.07",
* "unixVaporVer": "5.21"
* },
* "ios": {
* "uniVer": "x",
* "unixVer": "5.07",
* "unixVaporVer": "5.11"
* },
* "harmony": {
* "uniVer": "x",
* "unixVer": "5.07",
* "unixVaporVer": "5.07"
* }
* },
* "mp": {
* "weixin": {
* "uniVer": "x",
* "unixVer": "5.08"
* },
* "alipay": {
* "uniVer": "x",
* "unixVer": "5.31"
* }
* },
* "web": {
* "uniVer": "x",
* "unixVer": "5.07"
* }
* }
*/
// 禁用自动属性继承,手动控制属性绑定位置
defineOptions({
inheritAttrs: false,
externalClasses: ['badge-class']
})
// 定义组件属性接口
type Props = {
/**
* @description badge 的内容。为 "0" 时不显示 badge;为空字符串时显示圆点;有文字则显示文字
* @default ""
* @uniPlatform {
* "app": {
* "android": {
* "uniVer": "x",
* "unixVer": "5.07",
* "unixVaporVer": "5.21"
* },
* "ios": {
* "uniVer": "x",
* "unixVer": "5.07",
* "unixVaporVer": "5.11"
* },
* "harmony": {
* "uniVer": "x",
* "unixVer": "5.07",
* "unixVaporVer": "5.07"
* }
* },
* "web": {
* "uniVer": "x",
* "unixVer": "5.07"
* },
* "mp": {
* "weixin": {
* "uniVer": "x",
* "unixVer": "5.07"
* },
* "alipay": {
* "uniVer": "x",
* "unixVer": "5.31"
* }
* }
* }
*/
text? : string,
/**
* @description badge 的内联样式,用于覆盖内置 style
* @default ""
* @uniPlatform {
* "app": {
* "android": {
* "uniVer": "x",
* "unixVer": "5.07",
* "unixVaporVer": "5.21"
* },
* "ios": {
* "uniVer": "x",
* "unixVer": "5.07",
* "unixVaporVer": "5.11"
* },
* "harmony": {
* "uniVer": "x",
* "unixVer": "5.07",
* "unixVaporVer": "5.07"
* }
* },
* "web": {
* "uniVer": "x",
* "unixVer": "5.07"
* },
* "mp": {
* "weixin": {
* "uniVer": "x",
* "unixVer": "5.07"
* },
* "alipay": {
* "uniVer": "x",
* "unixVer": "5.31"
* }
* }
* }
*/
badgeStyle? : string,
/**
* @description badge 的样式类,用于覆盖内置 class
* @default ""
* @uniPlatform {
* "app": {
* "android": {
* "uniVer": "x",
* "unixVer": "5.07",
* "unixVaporVer": "5.21"
* },
* "ios": {
* "uniVer": "x",
* "unixVer": "5.07",
* "unixVaporVer": "5.11"
* },
* "harmony": {
* "uniVer": "x",
* "unixVer": "5.07",
* "unixVaporVer": "5.07"
* }
* },
* "web": {
* "uniVer": "x",
* "unixVer": "5.07"
* },
* "mp": {
* "weixin": {
* "uniVer": "x",
* "unixVer": "5.07"
* },
* "alipay": {
* "uniVer": "x",
* "unixVer": "5.31"
* }
* }
* }
*/
badgeClass? : string.ClassString,
/**
* @description 当有 slot 内容时,即使 text 为 "0" 也保留包裹层(badge-wrap),避免多个子 slot 时 flex 方向错乱
* @default false
* @uniPlatform {
* "app": {
* "android": {
* "uniVer": "x",
* "unixVer": "5.07",
* "unixVaporVer": "5.21"
* },
* "ios": {
* "uniVer": "x",
* "unixVer": "5.07",
* "unixVaporVer": "5.11"
* },
* "harmony": {
* "uniVer": "x",
* "unixVer": "5.07",
* "unixVaporVer": "5.07"
* }
* },
* "web": {
* "uniVer": "x",
* "unixVer": "5.07"
* },
* "mp": {
* "weixin": {
* "uniVer": "x",
* "unixVer": "5.07"
* },
* "alipay": {
* "uniVer": "x",
* "unixVer": "5.31"
* }
* }
* }
*/
alwaysWrapWithContent? : boolean
}
// 使用 withDefaults 设置默认值
const props = withDefaults(defineProps<Props>(), {
text: '',
badgeStyle: '',
badgeClass: '',
alwaysWrapWithContent: false
})
// 1. 获取插槽对象
const slots = useSlots();
// 2. 定义计算属性来判断默认插槽是否有内容
// TODO 这种判断方式的性能有待商榷,这利用了模板的隐式转换
const hasDefaultSlot = computed(() => {
// console.log('slot: ',slots['default']);
return slots['default'] != null;
});
</script>
<style>
.text {
/* background-color: rgba(225, 80, 80, 0.9); */ /* 有透明度*/
background-color: rgb(225, 80, 80); /* 无透明度*/
min-width: 14px;
height: 14px;
line-height: 14px;
border-radius: 7px;
/* padding-left: 4px; *//* 保证圆角不裁剪文字 */
/* padding-right: 4px; *//* 保证圆角不裁剪文字 */
font-size: 10px;
color: white;
text-align: center;
white-space: nowrap;
}
.dot {
background-color: rgb(225, 80, 80);
width: 8px;
height: 8px;
border-radius: 4px;
}
/* 有包裹内容,才定位在右上角。所以这个样式是一个单独的class,在slot有内容时才生效 */
.position {
position: absolute;
top: 0px; /* 定位在顶部*/
right: 0px; /* 定位在右边*/
transform: translate(50%, -50%); /* 中心向右上角偏移,保证中心在元素右上角顶点*/
}
.badge-wrap{
/* #ifdef WEB */
/* width: fit-content; */
/* #endif */
align-self: flex-start; /* 默认这样,不然width会变100%。但需要居中时得覆盖重设*/
}
</style>
+74
View File
@@ -0,0 +1,74 @@
{
"id": "uni-badge-view",
"displayName": "uni-badge-view 数字角标",
"version": "1.0.2",
"description": "数字角标(徽章)组件,在元素周围展示消息提醒,一般用于列表、九宫格、按钮等地方。",
"isExt": true,
"extUrl": "https://ext.dcloud.net.cn/plugin?id=27844",
"keywords": [
"badge",
"uni-ui",
"uniui",
"数字角标",
"徽章"
],
"repository": "https://gitcode.com/dcloud/uni-ui-x",
"engines": {
"HBuilderX": "^5.08",
"uni-app-x": "^5.08",
"uni-app": ""
},
"directories": {
"example": "../../temps/example_temps"
},
"dcloudext": {
"sale": {
"regular": {
"price": "0.00"
},
"sourcecode": {
"price": "0.00"
}
},
"contact": {
"qq": ""
},
"declaration": {
"ads": "无",
"data": "无",
"permissions": "无"
},
"type": "component-vue",
"darkmode": "√",
"i18n": "√",
"widescreen": "√",
"npmurl": ""
},
"uni_modules": {
"dependencies": [],
"encrypt": [],
"platforms": {
"client": {
"uni-app-x": {
"web": {
"safari": "√",
"chrome": "√"
},
"app": {
"android": "√",
"ios": "√",
"harmony": "√"
},
"mp": {
"weixin": "√"
}
}
},
"cloud": {
"tcb": "x",
"aliyun": "x",
"alipay": "x"
}
}
}
}
+34
View File
@@ -0,0 +1,34 @@
badge角标,可以用于显示红点、被红圈或其他颜色圈包裹的数字、文字。提醒用户此时有需要注意的新信息。
### 文件路径
项目下有一个 /pages/uni-ui/badge/badge.uvue 页面,里面演示了badge组件的各种用法。
### 设计
#### badge组件有多种用法:
1. 独立显示
如果没有slot内容,视为要显示独立的红点和数字,此时不是角标,就是普通的红点和圆背景数字。
在按钮或列表项的右侧,独立显示数字。也可以显示红点,但这种场景数字更多一些。
2. 作为一个容器组件,包含一个slot,在包裹内容的右上角显示一个角标view。
badge组件包裹一个目标view时,badge组件内部的角标view的中心点位于目标view的右上角顶点。
此时角标view是通过transform位移到右上角的,实际内容已经超出了容器本身。
所以需要注意容器的父级的设置,留出超出容器的尺寸(即top和right边距需要留出角标view的高度和宽度的一半),避免被父级裁剪。
#### badge的text属性的用法:
在badge作为容器组件时,text属性的不同设置,可以代表不同的效果。具体见属性章节。
#### 样式自定义
badge组件的badge-class和badge-style属性,直接作用在角标view上,可以修改角标view的样式。
角标view本质是一个text组件,可以覆盖前景、背景、位置等各种样式。
#### badge组件有如下属性:
- text
类型为 string|null
* 值为"0"时,不显示角标;所以永远不会显示一个为0的角标。此时直接显示slot子内容,不包裹外层,减少层级,提高性能;
* 值为null或""时,代表一个长宽为8px的红色圆点;
* 否则显示为该文字内容的圆角红底圈套文字。
- badge-class
直接作用于角标view的class
- badge-style
直接作用于角标view的style