chore: initial import

This commit is contained in:
liangjian
2026-06-29 09:42:53 +08:00
commit 9fea127de1
241 changed files with 82767 additions and 0 deletions

View File

@@ -0,0 +1,227 @@
<template>
<view v-if="show" class="tn-empty-class tn-empty" :style="[emptyStyle]">
<view
v-if="!isImage"
class="tn-empty__icon"
:class="[resolveIconClass(icon, mode)]"
:style="[iconStyle]"
></view>
<image
v-else
class="tn-empty__image"
:style="[imageStyle]"
:src="icon"
mode="widthFix"
></image>
<view
class="tn-empty__text"
:style="[textStyle]"
>{{ text ? text : localizedIcons[mode]}}</view>
<view v-if="$slots.default || $slots.$default" class="tn-empty__slot">
<slot/>
</view>
</view>
</template>
<script>
import { getCurrentLanguage } from '../../../utils/i18n'
function getLocalizedText(vm, zh, en) {
const language = vm && vm.$getLanguage ? vm.$getLanguage() : getCurrentLanguage()
return language === 'en' ? en : zh
}
export default {
name: 'tn-empty',
props: {
// 显示空白页
show: {
type: Boolean,
default: true
},
// 内置icon的名称
// 图片路径,建议使用绝对路径
icon: {
type: String,
default: ''
},
// 预置图标类型
mode: {
type: String,
default: 'data'
},
// 提示文字
text: {
type: String,
default: ''
},
// 文字颜色
textColor: {
type: String,
default: ''
},
// 文字大小,单位rpx
textSize: {
type: Number,
default: 0
},
// 图标颜色
iconColor: {
type: String,
default: ''
},
// 图标大小,单位rpx
iconSize: {
type: Number,
default: 0
},
// 图片宽度(当图标为图片时生效),单位rpx
imgWidth: {
type: Number,
default: 0
},
// 图片高度(当图标为图片时生效),单位rpx
imgHeight: {
type: Number,
default: 0
},
// 自定义组件样式
customStyle: {
type: Object,
default() {
return {}
}
}
},
computed: {
emptyStyle() {
let style = {}
Object.assign(style, this.customStyle)
return style
},
iconStyle() {
let style = {}
if (this.iconSize) {
style.fontSize = this.iconSize + 'rpx'
}
if (this.iconColor) {
style.color = this.iconColor
}
return style
},
imageStyle() {
let style = {}
if (this.imgWidth) {
style.width = this.imgWidth + 'rpx'
}
if (this.imgHeight) {
style.height = this.imgHeight + 'rpx'
}
return style
},
textStyle() {
let style = {}
if (this.textColor) {
style.color = this.textColor
}
if (this.textSize) {
style.fontSize = this.textSize + 'rpx'
}
return style
},
// 判断传递的icon是否为图片
isImage() {
return this.icon.indexOf('/') >= 0
},
localizedIcons() {
return {
cart: getLocalizedText(this, '购物车为空', 'Cart is empty'),
page: getLocalizedText(this, '页面不存在', 'Page not found'),
search: getLocalizedText(this, '搜索结果为空', 'No search results'),
address: getLocalizedText(this, '地址为空', 'No address available'),
network: getLocalizedText(this, '网络不通', 'Network unavailable'),
order: getLocalizedText(this, '订单为空', 'No orders available'),
coupon: getLocalizedText(this, '优惠券为空', 'No coupons available'),
favor: getLocalizedText(this, '暂无收藏', 'No favorites yet'),
permission: getLocalizedText(this, '无权限', 'No permission'),
history: getLocalizedText(this, '历史记录为空', 'No history available'),
message: getLocalizedText(this, '暂无消息', 'No messages yet'),
list: getLocalizedText(this, '列表为空', 'List is empty'),
data: getLocalizedText(this, '暂无数据', 'No data available'),
comment: getLocalizedText(this, '暂无评论', 'No comments yet')
}
}
},
methods: {
resolveIconClass(icon, mode) {
if (icon) {
if (icon.startsWith('tn-icon-')) {
return icon
}
return `tn-icon-${icon}`
}
const modeIconMap = {
cart: 'tn-icon-cart',
page: 'tn-icon-warning',
search: 'tn-icon-search',
address: 'tn-icon-location',
network: 'tn-icon-wifi-no',
order: 'tn-icon-order',
coupon: 'tn-icon-coupon',
favor: 'tn-icon-my-love',
permission: 'tn-icon-lock',
history: 'tn-icon-history',
message: 'tn-icon-message',
list: 'tn-icon-search-list',
data: 'tn-icon-charts-column',
comment: 'tn-icon-chat'
}
return modeIconMap[mode] || 'tn-icon-search-list'
}
},
data() {
return {}
}
}
</script>
<style lang="scss" scoped>
.tn-empty {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
&__icon {
margin-top: 14rpx;
color: #AAAAAA;
font-size: 90rpx;
}
&__image {
width: 160rpx;
height: 160rpx;
}
&__text {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
margin-top: 20rpx;
color: #AAAAAA;
font-size: 30rpx;
}
&__slot {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
margin-top: 20rpx;
}
}
</style>