效果图
util.js
export const showToast = msg => {
const ctx = getCurrentPages(), _t = ctx[ctx.length - 1];
if(_t) {
_t.$vm.$refs['toast'].show({
title: msg,
duration: 2500
});
}else
uni.showToast({
title: msg,
icon: 'none',
duration: 2500
})
}
pages.json
"insetLoader": {
"config": {
"Toast": "<Toast ref='toast' />"
},
"label": ["Toast"],
"rootEle": "view"
}
安装插件
npm install vue-inset-loader
vue.config.js
const path = require('path')
module.exports = {
configureWebpack: {
module: {
rules: [{
test: /\.vue$/,
use: {
loader: path.resolve(__dirname, "./node_modules/vue-inset-loader")
},
}]
},
}
}
components/toast/index.vue
<template>
<view v-if="showStatus" id="bn-toast-container" class="bn-toast-container" :class="parameter.verticalAlign" :style="boxStyle">
{{ parameter.title }}
</view>
</template>
<script>
export default {
name: 'Toast',
data() {
return {
showStatus: false,
toastHeight: 0,
toastWidth: 0,
parameter: {
title: '',
duration: 2500,
verticalAlign: 'center',
backgroundColor: '#000000a1',
color: '#FFFFFF'
}
};
},
computed: {
boxStyle() {
const _t = this;
const { backgroundColor, color } = _t.parameter;
const verticalAlign = _t.parameter.verticalAlign;
return verticalAlign ?
`left: 50%; opacity: ${(_t.toastWidth === 0 || _t.toastHeight === 0) ? 0 : 1}; background-color: ${backgroundColor}; color: ${color}; transform: translate(-${_t.toastWidth / 2}px, -${_t.toastHeight / 2}px); top: 50%`
: `left: 50%; opacity: ${(_t.toastWidth === 0 || _t.toastHeight === 0) ? 0 : 1}; background-color: ${backgroundColor}; color: ${color}; transform: translateX(-${_t.toastWidth / 2}px)`
}
},
methods: {
async show(parameter = {}) {
const _t = this;
for(const k in parameter) _t.parameter[k] = parameter[k]
_t.showStatus = true;
await _t.$nextTick();
const query = uni.createSelectorQuery().in(this);
query.select('#bn-toast-container').boundingClientRect(data => {
if (data) {
_t.toastHeight = data.height;
_t.toastWidth = data.width;
}
}).exec();
setTimeout(() => {
_t.showStatus = false;
}, _t.parameter.duration);
}
}
}
</script>
<style>
.bn-toast-container {
position: fixed;
opacity: 0;
z-index: 100000;
display: inline-block;
max-width: 375rpx;
padding: 11px 20px;
font-size: 13px;
text-align: center;
border-radius: 6px;
line-height: 20px;
margin-top: -32px;
transition: opacity .3s;
}
.bn-toast-container.top {
top: 88px;
top: 44px;
}
.bn-toast-container.bottom {
bottom: 50px;
}
</style>
main.js
import Toast from '@/components/toast'
Vue.component("Toast", Toast);