创建toast组件
index.wxmi
<!--components/toast/index.wxml-->
<cover-view wx:if="{{show}}" class="toast {{type==='confirm' ? 'confirm' : ''}} {{show === null ? '' : show?'fadeIn':'fadeDown'}} {{mask?'toast-mask':''}}">
<cover-view class="toast-container">
<cover-view wx:if="{{type === 'success'}}">success</cover-view>
<cover-view wx:if="{{type === 'fail'}}">fail</cover-view>
<!-- cover-view 内文字在IOS 被遮挡截取显示不全的问题
解决:在文字后面添加一个全角空格 就能解决该问题 -->
<cover-view wx:if="{{message}}" class="toast-message">{{message}} </cover-view>
<cover-view wx:if="{{tip}}" class="toast-message-tip">{{tip}}</cover-view>
<cover-view wx:if="{{type === 'confirm'}}" class="confrim_button">
<cover-view class="confirm-left" data-value="{{0}}" bindtap="confirmCallback">取消</cover-view>
<cover-view class="confirm-right" data-value="{{1}}" bindtap="confirmCallback">确认</cover-view>
</cover-view>
</cover-view>
</cover-view>
index.less
/* components/toast/index.wxss */
.toast {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
display: flex;
z-index: 10000;
align-items: center;
justify-content: center;
opacity: 0;
visibility: hidden;
}
.toast.confirm .toast-container {
padding: 0;
padding-top: 52rpx;
}
.toast-message {
white-space: normal !important;
line-height: 40rpx !important;
}
.toast.confirm .toast-message,
.toast.confirm .toast-message-tip {
padding: 0 28rpx;
}
.toast.confirm .toast-message-tip {
padding-bottom: 52rpx;
}
.toast-container {
position: relative;
background: #505050;
border-radius: 20rpx;
max-width: 80%;
padding: 39rpx 60rpx;
z-index: 1001;
box-sizing: border-box;
overflow: hidden;
font-size: 28rpx;
font-weight: 400;
color: #ffffff;
line-height: 40rpx;
white-space: pre-wrap;
}
@keyframes aniIn {
0% {
opacity: 0;
visibility: visible;
}
100% {
opacity: 1;
visibility: visible;
}
}
@keyframes aniDown {
0% {
opacity: 1;
visibility: visible;
}
100% {
opacity: 0;
visibility: hidden;
}
}
.fadeDown {
animation: aniDown 0.2s linear;
animation-fill-mode: forwards;
}
.fadeIn {
animation: aniIn 0.2s linear;
animation-fill-mode: forwards;
}
.toast-close {
position: absolute;
top: 28rpx;
right: 28rpx;
}
.toast-close .close_image {
width: 48rpx;
height: 48rpx;
}
.toast-message-tip {
font-size: 30rpx;
font-weight: 400;
color: #262626;
line-height: 40rpx;
margin-top: 28rpx;
text-align: center;
white-space: pre-wrap;
}
.confrim_button {
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
padding: 0 88rpx 48rpx 88rpx;
}
.confrim_button .confirm-left,
.confrim_button .confirm-right {
height: 70rpx;
line-height: 70rpx;
width: 200rpx;
border-radius: 35rpx;
border: 2rpx solid #c2c2c2;
text-align: center;
color: #565656;
box-sizing: border-box;
}
.confrim_button .confirm-right {
color: #ffffff;
border: none;
background: linear-gradient(270deg, #ff743b 0%, #ff312a 100%);
}
index.json
{
"component": true,
"usingComponents": {}
}
index.ts
// components/toast/index.js
Component({
/**
* 组件的属性列表
*/
properties: {
mask: {
type: Boolean,
value: true,
},
show: {
type: null,
value: null,
},
duration: {
type: Number,
value: 2000,
},
message: {
type: String,
value: "",
},
tip: {
type: String,
value: "",
},
type: {
type: String,
value: "text",
},
closeButton: {
type: Boolean,
value: true,
},
className: {
type: String,
value: "",
},
},
/**
* 组件的初始数据
*/
data: {},
/**
* 组件的方法列表
*/
methods: {},
});
toast.js
let defaultOptions = {
type: "text",
mask: true,
message: "",
show: true,
duration: 2000,
selector: "#toast",
closeButton: true,
callback: null,
tip: "",
className: "",
};
function getContext() {
const pages = getCurrentPages();
return pages[pages.length - 1];
}
function isObj(message) {
return message !== null && typeof message === "object"
? message
: { message };
}
let queue = [];
function Toast(currentOption) {
let options = Object.assign({}, defaultOptions, isObj(currentOption));
let context = getContext();
let toast = context.selectComponent(options.selector);
if (!toast) {
console.error(
"未找到 toast 节点, 请确认 selector 及 context 是否正确, 检查页面是否引入toast组件!"
);
return;
}
toast.clear = (e) => {
toast.setData({ show: false });
};
toast.confirmCallback = (e) => {
clearTimeout(toast.timer);
toast.clear();
toast.setData({ show: false });
options.callback && options.callback(e.target.dataset.value);
};
queue.push(toast);
toast.setData(options);
clearTimeout(toast.timer);
if (options.duration > 0) {
toast.timer = setTimeout(() => {
toast.clear();
options.callback && options.callback();
queue = queue.filter((item) => item !== toast);
}, options.duration);
}
return toast;
}
const createMethod = (type) => (options) =>
Toast(Object.assign({}, isObj(type), isObj(options)));
Toast.success = createMethod("success");
Toast.fail = createMethod("fail");
Toast.confirm = createMethod({
type: "confirm",
closeButton: false,
duration: 0,
});
Toast.loading = (message) => {
wx.showLoading({
title: message || "加载中...",
mask: true,
});
};
Toast.loading.clear = () => {
wx.hideLoading();
};
Toast.clear = () => {
queue.forEach((toast) => {
toast.clear();
});
queue = [];
};
export default Toast;
使用
index.json
index.wxml
<toast id="toast"></toast>
index.ts
import Toast from "../../../components/toast/toast.js";
Toast({
message: "券面值过大,建议券面值与使用门槛的比例小于等于0.4",
});