几乎每个h5页面都要有空数据展示逻辑,一个个写又太耗费时间。
组件 - 不灵活版本
<template>
<div class="empty-page">
<div class="empty-wrapper">
<div class="img-wrapper">
<img :src="url" />
<p class="empty-text">{{ text }}</p>
<!-- 补充说明 -->
<p v-if="descText" class="empty-desc">{{ descText }}</p>
<!-- 按钮 -->
</div>
<div class="btn-wrapper" v-if="btn">
<van-button class="empty-btn" size="small" type="primary" @click="onClick">{{ btn }}</van-button>
</div>
</div>
</div>
</template>
<script>
export default {
components: {},
props: {
// 类型
emptyType: {
type: String,
default: 'noData'
},
// 图片地址
imgUrl: {
type: String,
default: ''
},
// 描述
emptyText: {
type: String,
default: ''
},
// 描述补充
emptyDescText: {
type: String,
default: ''
},
// 按钮文案
btnText: {
type: String,
default: ''
}
},
data() {
return {
emptyTypeToImgMap: {
// 暂无内容
noData: {
img: require('@/assets/images/empty/noData.png'),
text: '暂无内容'
},
// 加载失败
loadFail: {
img: require('@/assets/images/empty/loadFail.png'),
text: '加载失败',
descText: '请稍后重试~',
btn: '重试'
},
// 服务器异常
serverError: {
img: require('@/assets/images/empty/serverError.png'),
text: '服务器异常',
descText: '网络连接失败,请检查网络后重试~',
btn: '刷新'
},
// 网络异常
networkError: {
img: require('@/assets/images/empty/networkError.png'),
text: '网络异常',
descText: '正在抢修,请稍后刷新试试~',
btn: '重试'
}
}
}
},
computed: {
url() {
return this.imgUrl || this.emptyTypeToImgMap[this.emptyType].img
},
text() {
return this.description || this.emptyTypeToImgMap[this.emptyType].text
},
descText() {
return this.btnText || this.emptyTypeToImgMap[this.emptyType].descText
},
btn() {
return this.btnText || this.emptyTypeToImgMap[this.emptyType].btn
}
},
watch: {},
created() {},
mounted() {},
methods: {
onClick() {
this.$emit('click')
}
}
}
</script>
动态挂载,直接使用
Exception.vue
<template>
<!-- 异常内容区域 -->
<div class="exception_ctt">
<div>
<!-- 根据type显示不同的图片 -->
<img src="@/assets/images/new_empty.png" v-if="type === 'emptyData'" />
<img src="@/assets/images/loadFail.png" v-if="type === 'loadFail'" />
<img src="@/assets/images/serverError.png" v-if="type === 'serverError'" />
<!-- 如果text1存在,则显示text1内容 -->
<div class="text1" v-if="text1">{{ text1 }}</div>
<!-- 如果text2存在,则显示text2内容 -->
<div class="text2" v-if="text2">{{ text2 }}</div>
<!-- 如果reloadText存在,则显示重载按钮 -->
<div class="reload" v-if="reloadText" @click="toReload">{{ reloadText }}</div>
</div>
</div>
</template>
<script>
export default {
name: 'StarryDialog',
data() {
return {
// type表示异常类型
type: '',
// text1用于显示第一行文本信息
text1: '',
// text2用于显示第二行文本信息
text2: '',
// reloadText用于显示重载按钮的文本
reloadText: ''
}
},
created() {},
methods: {
/**
* 重载方法
* 当用户点击重载按钮时调用此方法
* 触发onReload回调函数,如果存在的话
*/
toReload() {
this.onReload && this.onReload()
}
}
}
</script>
exception.js
主要流程:
// 导入Vue和异常组件
import Vue from 'vue'
import Exception from '@/components/Exception.vue'
// 1. 创建组件实例 (实例化通过 extend 生成的构造器)
const ExceptionConstructor = Vue.extend(Exception)
/**
* 在指定的DOM元素中渲染异常组件
* @param {HTMLElement} dom - 要渲染异常组件的DOM元素如果不需要添加到DOM树中,则可以省略
* @param {Object} data - 传递给异常组件的数据
*/
const exception = (dom, data) => {
// 创建一个新的异常组件实例,指定DOM元素和数据
const newDom = new ExceptionConstructor({
el: document.createElement('div'),// 2. 创建挂载锚点
data() {
return data
}// 3. 注入响应式数据
})
// 4. 手动 DOM 操作挂载。
// 如果提供了DOM元素,则清空其内容并appendChild新的异常组件DOM元素
if (dom) {
dom.innerHTML = '' // 清空容器
dom.appendChild(newDom.$el) // 插入组件 DOM
}
}
// 导出异常组件渲染函数
export default exception
使用:
要有一个div来接收
<div ref="exceptionRef"/>
loadError() {
this.exceptionFlag = true
this.$nextTick(() => {
this.showException(this.$refs.exceptionRef, {
type: 'loadFail',
text1: '加载失败',
text2: '请稍后重试~',
reloadText: '重试',
onReload: this.onRefresh
})
})
}