wx-mini-weview
Version:
weixin UI
224 lines (191 loc) • 6.28 kB
JavaScript
const { WvComponentHandler } = require('../../behaviors/WvComponentHandler');
Component({
options: {
styleIsolation: 'apply-shared',
},
behaviors: [
WvComponentHandler({
handleMethods: {
tap: {
showMsg: {},
showSlot: {},
hide: {},
hideAll: {}
}
}
}),
],
properties: {
zIndex: { type: Number, value: 9000 },
topOffset: { type: String, value: 'var(--wv-margin-default)' },
bottomOffset: { type: String, value: 'var(--wv-margin-default)' },
leftOffset: { type: String, value: 'var(--wv-margin-default)' },
rightOffset: { type: String, value: 'var(--wv-margin-default)' },
position: { type: String, value: 'center' },
showAnimationType: { type: String, value: "fade" },
hideAnimationType: { type: String, value: "fade" },
animationDuration: { type: Number, value: 300 },
theme: { type: String, value: 'wv-theme-heavy wv-content-light' },
icon: { type: String, value: 'bi-info-circle-fill' },
iconColor: { type: String, value: '' },
iconSize: {
type: String,
value: '30rpx' // 支持rpx/px/em单位
},
iconMode: {
type: String,
value: 'inline' // inline | left | center | right
},
msgColor: { type: String, value: '' },
bgOpacity: { type: Number, value: 0.8 },
showMask: { type: Boolean, value: false },
maskClosable: { type: Boolean, value: true },
queueMode: { type: Boolean, value: true }
},
data: {
messages: [],
_messageCounter: 0
},
lifetimes: {
attached() {
const that = this;
if (that.data.showMask) {
that.mask = that.selectComponent('#wv-mask-in-toast');
}
}
},
observers: {
'showMask': function(showMask) {
const that = this;
if (showMask) {
// Use nextTick to ensure the mask element is fully rendered
wx.nextTick(() => {
that.mask = that.selectComponent('#wv-mask-in-toast');
});
} else {
that.mask = null;
}
}
},
methods: {
showMsg(content, duration = 2000, options = {}, callback = null) {
const that = this
this._addToQueue({
type: "msg",
content,
duration,
theme: options.theme || this.data.theme,
icon: options.icon || this.data.icon,
iconColor: options.iconColor || this.data.iconColor,
iconSize: options.iconSize || this.data.iconSize,
iconMode: options.iconMode || this.data.iconMode,
msgColor: options.msgColor || this.data.msgColor,
bgOpacity: options.bgOpacity || this.data.bgOpacity,
animationClass: `wv-toast-${this.data.showAnimationType}-in`,
callback
});
},
showSlot(duration = 0, callback = null, onHide = null) {
const that = this
that._addToQueue({
type: 'slot',
duration,
animationClass: `wv-toast-${this.data.showAnimationType}-in`,
callback: onHide
});
if (typeof callback === 'function') callback();
},
_addToQueue(item) {
const that = this;
const uniqueId = `${Date.now()}_${that.data._messageCounter++}`;
const newItem = {
...item,
id_msg: uniqueId,
timer: item.duration > 0 ? setTimeout(() => {
that._removeWithAnimation(newItem.id_msg);
}, item.duration) : null
};
let slotFiltered = []
if(that.data.queueMode){
slotFiltered = that.data.messages.filter(msg => msg.type !== 'slot');
slotFiltered = [...slotFiltered, newItem]
}else{
slotFiltered = [newItem]
}
that.setData({
messages: slotFiltered,
}, () => {
if (that.data.showMask) {
if (!that.mask) {
that.mask = that.selectComponent('#wv-mask-in-toast');
}
if(that.mask) {
that.mask.show()
}
}
});
},
_removeWithAnimation(id_msg) {
const that = this;
const index = that.data.messages.findIndex(m => m.id_msg === id_msg);
if (index === -1) return;
const targetMsg = that.data.messages[index];
const callback = targetMsg.callback;
const animationClass = `wv-toast-${that.data.hideAnimationType}-out`;
const updatedMessages = that.data.messages.map((msg, i) =>
i === index ? { ...msg, animationClass: animationClass } : msg
);
that.setData({
messages: updatedMessages
}, () => {
setTimeout(() => {
that.setData({
messages: that.data.messages.filter(m => m.id_msg !== id_msg)
}, () => {
if (typeof callback === 'function') {
callback({
id: id_msg,
type: targetMsg.type,
content: targetMsg.content
});
}
if (that.data.messages.length === 0) that.hideAll();
});
}, that.data.animationDuration);
});
},
onMaskTap() {
const that = this;
if (that.data.maskClosable) that._doClose();
},
_doClose(targetId = null, callback) {
const that = this;
if (that.data.messages.length === 0) return;
let target;
if (targetId) {
target = that.data.messages.find(item => item.id_msg === targetId);
} else {
target = that.data.queueMode ?
that.data.messages[0] :
that.data.messages.slice(-1)[0];
}
if (target) {
if (target.timer) clearTimeout(target.timer);
that._removeWithAnimation(target.id_msg);
}
that.triggerEvent('close')
if(typeof callback === 'function') callback()
},
hide(callback = null) {
const that = this;
that._doClose(null, callback);
},
hideAll() {
const that = this;
that.setData({
messages: [],
});
if (that.data.showMask && that.mask) that.mask.hide();
}
}
});