Initial commit
This commit is contained in:
@@ -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>
|
||||
@@ -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"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user