乐趣区

Vue自定义全局Toast和Loading

如果我们的 Vue 项目中没有用到任何 UI 框架的话,为了更好的用户体验,肯定会用到 loading 和 toast。那么我们就自定义这两个组件吧。
1、Toast 组件
首先,在 common 下新建 global 文件夹,存放我们的 toast.vue 和 toast.js 两个文件(当然文件的具体位置你可以自行安排)。
(1). toast.vue
<template lang=”html”>
<div v-if=”isShowToast” class=”toast-container” @touchmove.prevent>
<!– 这里 content 为双花括号 –>
<span class=”loading-txt”>{content}</span>
</div>
</template>

<script>
export default {
data () {
return {
isShowToast: true,
content: ”
}
}
}
</script>

<!– Add “scoped” attribute to limit CSS to this component only –>
<style scoped>
.toast-container {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(255, 255, 255, 0.1);
}
.toast-msg {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 60%;
padding: 35px;
border-radius: 10px;
font-size: 28px;
line-height: 36px;
background: #eee;
color: #666;
}
</style>
(2). toast.js
import Vue from ‘Vue’
import ToastComponent from ‘./Toast.vue’

const Toast = {}
let showToast = false // 存储 loading 显示状态
let toastNode = null // 存储 loading 节点元素
const ToastConstructor = Vue.extend(ToastComponent)

Toast.install = function (Vue, options) {
// 参数
var opt = {
duration: ‘1200’
}
for (var property in options) {
opt[property] = options[property]
}
Vue.prototype.$toast = function (tips, type) {
if (type === ‘hide’) {
toastNode.isShowToast = showToast = false
} else {
if (showToast) {
// 如果 toast 还在,则不再执行
return
}
toastNode = new ToastConstructor({
data: {
isShowToast: showToast,
content: tips
}
})
toastNode.$mount() // 挂在实例,为了获取下面的 toastNode.$el
document.body.appendChild(toastNode.$el)
toastNode.isShowToast = showToast = true
setTimeout(function () {
toastNode.isShowToast = showToast = false
}, opt.duration)
}
};

[‘show’, ‘hide’].forEach(function (type) {
Vue.prototype.$toast[type] = function (tips) {
return Vue.prototype.$toast(tips, type)
}
})
}

export default Toast
然后,我们需要把写好的组件在 /src/main.js 中引用一下。
import Toast from ‘./components/common/global/toast’

Vue.use(Toast)
最后,怎么使用呢?只需在要用的地方 this.$toast.show(‘hello world’)
2、Loading 组件
loading 组件只需要照着 toast 组件搬过来,稍微改下就可以了。
首先,在 common 下新建 global 文件夹,存放我们的 loading.vue 和 loading.js 两个文件。
(1). loading.vue
<template lang=”html”>
<div v-if=”isShowLoading” class=”loading-container”>
<div class=”loading-box”>
<img class=”loading-img” :src=”require(‘../../../assets/images/loading.png’)”>
<!– 这里 content 为双花括号 –>
<span class=”loading-txt”>{content}</span>
</div>
</div>
</template>

<script>
export default {
data () {
return {
isShowLoading: false,
content: ”
}
}
}
</script>

<!– Add “scoped” attribute to limit CSS to this component only –>
<style scoped>
.loading-container {
display: flex;
justify-content: center;
align-items: center;
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0);
z-index: 1000;
}
.loading-box {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
width: 150px;
height: 150px;
border-radius: 10px;
background: #e5e5e5;
}
.loading-img {
width: 70px;
height: 70px;
animation: rotating 2s linear infinite;
}
@keyframes rotating {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(1turn);
}
}
.loading-txt {
display: flex;
justify-content: center;
align-items: center;
font-size: 24px;
color: #666;
}
</style>
(2). loading.js
import Vue from ‘Vue’
import LoadingComponent from ‘./Loading.vue’

const Loading = {}
let showLoading = false // 存储 loading 显示状态
let loadingNode = null // 存储 loading 节点元素
const LoadingConstructor = Vue.extend(LoadingComponent)

Loading.install = function (Vue) {
Vue.prototype.$loading = function (tips, type) {
if (type === ‘hide’) {
loadingNode.isShowLoading = showLoading = false
} else {
if (showLoading) {
// 如果 loading 还在,则不再执行
return
}
loadingNode = new LoadingConstructor({
data: {
isShowLoading: showLoading,
content: tips
}
})
loadingNode.$mount() // 挂在实例,为了获取下面的 loadingNode.$el
document.body.appendChild(loadingNode.$el)
loadingNode.isShowLoading = showLoading = true
}
};

[‘show’, ‘hide’].forEach(function (type) {
Vue.prototype.$loading[type] = function (tips) {
return Vue.prototype.$loading(tips, type)
}
})
}

export default Loading
然后,在 /src/main.js 中引用一下 loading 组件。
import Loading from ‘./components/common/global/loading’

Vue.use(Loading)
最后,只需在要用的地方 this.$loading.show(‘hello world’)、this.$loading.hide()

退出移动版