Files
2026-06-29 09:42:53 +08:00

228 lines
5.7 KiB
Vue
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<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>