-
+
-
@@ -34,7 +34,6 @@ import {
} from 'vue';
import { CheckCircleFilledIcon, ErrorCircleFilledIcon, CloseIcon } from 'tdesign-icons-vue-next';
import { isFunction } from 'lodash';
-import { off } from 'process';
import messageProps from './props';
import { DrawMarquee } from './type';
import config from '../config';
@@ -53,7 +52,7 @@ export default defineComponent({
name,
components: { TNode },
props: messageProps,
- emits: ['change', 'open', 'opened', 'close', 'closed'],
+ emits: ['durationEnd', 'closeBtnClick'],
setup(props: any, context) {
const emitEvent = useEmitEvent(props, context.emit);
const internalInstance = getCurrentInstance();
@@ -68,12 +67,12 @@ export default defineComponent({
marquee: false,
speed: 50,
loop: -1, // 值为 -1 表示循环播放,值为 0 表示不循环播放
- delay: 0,
+ delay: 300,
},
});
const { visible, modelValue } = toRefs(props);
- const [currentVisible, setVisible] = useVModel(visible, modelValue, props.defaultVisible, props.onChange);
+ const [currentVisible, setVisible] = useVModel(visible, modelValue, props.defaultVisible);
const rootClasses = computed(() => ({
[name]: true,
[`${name}--${props.theme}`]: true,
@@ -129,8 +128,7 @@ export default defineComponent({
return renderTNode(internalInstance, 'closeBtn');
}
if (closeBtn) {
- const closeIcon = h(CloseIcon);
- return closeIcon;
+ return h(CloseIcon);
}
return null;
});
@@ -149,17 +147,20 @@ export default defineComponent({
if (!props?.marquee || (props?.marquee as DrawMarquee)?.loop === 0) {
return;
}
- // 初始化动画参数
- if (typeof props.marquee === 'boolean') {
- state.scroll = { ...state.scroll, marquee: props.marquee };
- }
- const marquee = props.marquee as DrawMarquee;
+
+ const { loop, speed, delay } = state.scroll;
+
state.scroll = {
marquee: true,
- loop: typeof marquee?.loop === 'undefined' ? state.scroll.loop : marquee.loop,
- speed: marquee.speed ?? state.scroll.speed,
- delay: marquee.delay ?? state.scroll.delay,
+ // 负数统一当作循环播放
+ loop: Math.max(props.marquee?.loop, -1) || loop,
+ // 速度必须为正数
+ speed: Math.max(props.marquee?.speed, 1) || speed,
+ // 延迟不可为负数
+ delay: Math.max(props.marquee?.delay, 0) || delay,
};
+ state.offset = 0;
+
// 设置动画
setTimeout(() => {
const textWrapDOMWidth = textWrapDOM.value?.getBoundingClientRect().width;
@@ -173,16 +174,22 @@ export default defineComponent({
// 动画结束后,初始化动画
const handleTransitionend = () => {
+ resetTransition();
+
+ if (state.scroll.loop === -1) {
+ return;
+ }
+
state.scroll.loop = --state.scroll.loop;
+
if (state.scroll.loop === 0) {
- state.scroll = {
- ...state.scroll,
- marquee: false,
- };
- return;
+ state.scroll.marquee = false;
}
- state.offset = state.listWidth;
+ };
+
+ const resetTransition = () => {
state.duration = 0;
+ state.offset = state.listWidth;
setTimeout(() => {
state.offset = -state.itemWidth;
@@ -190,8 +197,8 @@ export default defineComponent({
}, 0);
};
- const onClose = () => {
- emitEvent('close');
+ const onCloseBtnClick = () => {
+ emitEvent('closeBtnClick');
setVisible(false);
};
@@ -199,7 +206,7 @@ export default defineComponent({
if (props.duration > 0) {
setTimeout(() => {
emitEvent('durationEnd');
- onClose();
+ onCloseBtnClick();
}, props.duration);
}
};
@@ -216,14 +223,9 @@ export default defineComponent({
() => currentVisible.value,
(val) => {
if (val === false) return;
- emitEvent('open');
setVisible(true);
handleDuration();
- nextTick(() => {
- state.offset = state.listWidth;
- state.duration = 0;
- handleScrolling();
- });
+ nextTick(handleScrolling);
},
);
@@ -240,10 +242,8 @@ export default defineComponent({
textWrapDOM,
textDOM,
animateStyle,
- onClose,
+ onCloseBtnClick,
handleTransitionend,
- afterEnter: () => emitEvent('opened'),
- afterLeave: () => emitEvent('closed'),
};
},
});
diff --git a/src/message/props.ts b/src/message/props.ts
index 65d44e28a..2f7aad8da 100644
--- a/src/message/props.ts
+++ b/src/message/props.ts
@@ -19,8 +19,8 @@ export default {
},
/** 关闭按钮,可以自定义。值为 true 显示默认关闭按钮,值为 false 不显示关闭按钮。值类型为 string 则直接显示值,如:“关闭”。也可以完全自定义按钮 */
closeBtn: {
- type: [Boolean, Function] as PropType
,
- default: false,
+ type: [String, Boolean, Function] as PropType,
+ default: undefined,
},
/** 用于自定义消息弹出内容 */
content: {
@@ -31,11 +31,15 @@ export default {
type: Number,
default: 3000,
},
- /** 消息提醒前面的图标。值为 true 则根据 theme 显示对应的图标,值为 false 则不显示图标。值为 'info' 或 'bell' 则显示组件内置图标。也可以完全自定义图标节点 */
+ /** 用于自定义消息前面的图标,优先级大于 theme 设定的图标。值为 false 则不显示图标,值为 true 显示 theme 设定图标 */
icon: {
type: [Boolean, Function] as PropType,
default: true,
},
+ /** 链接名称。值为字符串表示链接名称,值为 Object 类型,表示透传至 Link */
+ link: {
+ type: [String, Object, Function] as PropType,
+ },
/** 跑马灯效果。speed 指速度控制;loop 指循环播放次数,值为 -1 表示循环播放,值为 0 表示不循环播放;delay 表示延迟多久开始播放 */
marquee: {
type: [Boolean, Object] as PropType,
@@ -69,14 +73,20 @@ export default {
zIndex: {
type: Number,
},
- /** 可见性变化时触发 */
+ /** 已废弃。可见性变化时触发 */
onChange: Function as PropType,
- /** 关闭消息时触发 */
+ /** 已废弃。关闭消息时触发 */
onClose: Function as PropType,
- /** 关闭Message时并且动画结束后触发 */
+ /** 当关闭按钮存在时,用户点击关闭按钮触发 */
+ onCloseBtnClick: Function as PropType,
+ /** 已废弃。关闭消息并且动画结束后触发 */
onClosed: Function as PropType,
- /** 展示Message时触发 */
+ /** 计时结束后触发 */
+ onDurationEnd: Function as PropType,
+ /** 当link链接存在时,点击链接文本时触发 */
+ onLinkClick: Function as PropType,
+ /** 已废弃。展示Message时触发 */
onOpen: Function as PropType,
- /** 展示Message时并且动画结束后触发 */
+ /** 已废弃。展示Message时并且动画结束后触发 */
onOpened: Function as PropType,
};
diff --git a/src/message/style/index.js b/src/message/style/index.js
index a433a27b4..b19cb1837 100644
--- a/src/message/style/index.js
+++ b/src/message/style/index.js
@@ -1 +1 @@
-import '../../_common/style/mobile/components/message/_index.less';
+import '../../_common/style/mobile/components/message/v2/_index.less';
diff --git a/src/message/type.ts b/src/message/type.ts
index 9ad6056f8..0369c9008 100644
--- a/src/message/type.ts
+++ b/src/message/type.ts
@@ -15,7 +15,7 @@ export interface TdMessageProps {
/**
* 关闭按钮,可以自定义。值为 true 显示默认关闭按钮,值为 false 不显示关闭按钮。值类型为 string 则直接显示值,如:“关闭”。也可以完全自定义按钮
*/
- closeBtn?: boolean | TNode;
+ closeBtn?: string | boolean | TNode;
/**
* 用于自定义消息弹出内容
*/
@@ -26,10 +26,14 @@ export interface TdMessageProps {
*/
duration?: number;
/**
- * 消息提醒前面的图标。值为 true 则根据 theme 显示对应的图标,值为 false 则不显示图标。值为 'info' 或 'bell' 则显示组件内置图标。也可以完全自定义图标节点
+ * 用于自定义消息前面的图标,优先级大于 theme 设定的图标。值为 false 则不显示图标,值为 true 显示 theme 设定图标
* @default true
*/
icon?: boolean | TNode;
+ /**
+ * 链接名称。值为字符串表示链接名称,值为 Object 类型,表示透传至 Link
+ */
+ link?: string | object | TNode;
/**
* 跑马灯效果。speed 指速度控制;loop 指循环播放次数,值为 -1 表示循环播放,值为 0 表示不循环播放;delay 表示延迟多久开始播放
* @default false
@@ -65,22 +69,39 @@ export interface TdMessageProps {
zIndex?: number;
/**
* 可见性变化时触发
+ * @deprecated
*/
onChange?: (visible: boolean) => void;
/**
* 关闭消息时触发
+ * @deprecated
+ */
+ onClose?: (context: { trigger: 'close-click' | 'duration-end'; e?: MouseEvent }) => void;
+ /**
+ * 当关闭按钮存在时,用户点击关闭按钮触发
*/
- onClose?: (context?: { trigger: 'duration' | 'close-click' }) => void;
+ onCloseBtnClick?: (context: { e: MouseEvent }) => void;
/**
- * 关闭Message时并且动画结束后触发
+ * 关闭消息并且动画结束后触发
+ * @deprecated
*/
onClosed?: () => void;
+ /**
+ * 计时结束后触发
+ */
+ onDurationEnd?: () => void;
+ /**
+ * 当link链接存在时,点击链接文本时触发
+ */
+ onLinkClick?: (context: { e: MouseEvent }) => void;
/**
* 展示Message时触发
+ * @deprecated
*/
onOpen?: () => void;
/**
* 展示Message时并且动画结束后触发
+ * @deprecated
*/
onOpened?: () => void;
}