UNPKG

ivue-material-plus

Version:

A high quality UI components Library with Vue.js

1 lines 11.9 kB
{"version":3,"file":"index2.mjs","sources":["../../../../../src/components/ivue-notice-bar/index.vue"],"sourcesContent":["<template>\r\n <div :class=\"wrapperClasses\" :style=\"wrapperStyles\" v-show=\"data.show\">\r\n <!-- icon -->\r\n <div :class=\"`${prefixCls}-left`\">\r\n <slot name=\"leftIcon\">\r\n <ivue-icon :class=\"`${prefixCls}-icon`\" v-if=\"leftIcon\">{{\r\n leftIcon\r\n }}</ivue-icon>\r\n </slot>\r\n </div>\r\n <!-- 内容 -->\r\n <div :class=\"`${prefixCls}-text--wrapper`\" ref=\"contentWrapper\">\r\n <div\r\n :class=\"textClasses\"\r\n :style=\"textStyles\"\r\n :onTransitionend=\"handleTransitionEnd\"\r\n ref=\"content\"\r\n >\r\n <slot>{{ text }}</slot>\r\n </div>\r\n </div>\r\n <!-- icon -->\r\n <div :class=\"`${prefixCls}-right`\">\r\n <slot name=\"nextIcon\">\r\n <!-- 关闭按钮 -->\r\n <ivue-icon\r\n :class=\"`${prefixCls}-icon`\"\r\n @click=\"handleClose\"\r\n v-if=\"mode === 'closeable'\"\r\n >close</ivue-icon\r\n >\r\n <!-- 链接按钮 -->\r\n <ivue-icon\r\n :class=\"`${prefixCls}-icon`\"\r\n @click=\"handleLink\"\r\n v-if=\"mode === 'link'\"\r\n >arrow_forward_ios</ivue-icon\r\n >\r\n </slot>\r\n </div>\r\n </div>\r\n</template>\r\n\r\n<script lang=\"ts\">\r\nimport {\r\n defineComponent,\r\n ref,\r\n reactive,\r\n computed,\r\n onMounted,\r\n onActivated,\r\n nextTick,\r\n onUnmounted,\r\n onDeactivated,\r\n watch,\r\n} from 'vue';\r\nimport { isDef } from '../../utils/validate';\r\nimport { doubleRaf, raf, isCssColor } from '../../utils/helpers';\r\nimport { on, off } from '../../utils/dom';\r\nimport IvueIcon from '../ivue-icon';\r\nimport { oneOf } from '../../utils/assist';\r\n\r\n// type\r\nimport type { Props, Data } from './types/notice-bar';\r\n\r\nconst prefixCls = 'ivue-notice-bar';\r\n\r\nexport default defineComponent({\r\n name: prefixCls,\r\n emits: ['on-replay', 'on-close', 'on-link'],\r\n props: {\r\n /**\r\n * 文本\r\n *\r\n * @type {String}\r\n */\r\n text: {\r\n type: String,\r\n },\r\n /**\r\n * 滚动速率 (px/s)\r\n *\r\n * @type {Number}\r\n */\r\n speed: {\r\n type: Number,\r\n default: 60,\r\n },\r\n /**\r\n * 动画延迟时间 (s)\r\n *\r\n * @type {Number}\r\n */\r\n delay: {\r\n type: Number,\r\n default: 1,\r\n },\r\n /**\r\n * 是否开启滚动播放,内容长度溢出时默认开启\r\n *\r\n * @type {Boolean}\r\n */\r\n scrollable: {\r\n type: Boolean,\r\n default: false,\r\n },\r\n /**\r\n * 模式\r\n *\r\n * @type {String}\r\n */\r\n mode: {\r\n type: String,\r\n validator(value: string) {\r\n return oneOf(value, ['closeable', 'link']);\r\n },\r\n },\r\n /**\r\n * 是否开启文本换行,只在禁用滚动时生效\r\n *\r\n * @type {Boolean}\r\n */\r\n wrapable: {\r\n type: Boolean,\r\n },\r\n /**\r\n * 左边按钮\r\n *\r\n * @type {String}\r\n */\r\n leftIcon: {\r\n type: String,\r\n },\r\n /**\r\n * 背景\r\n *\r\n * @type {String | Array}\r\n */\r\n background: {\r\n type: [String, Array],\r\n },\r\n /**\r\n * 文字颜色\r\n *\r\n * @type {String}\r\n */\r\n textColor: {\r\n type: String,\r\n },\r\n },\r\n setup(props: Props, { emit }) {\r\n // dom\r\n const contentWrapper = ref<HTMLElement>();\r\n const content = ref<HTMLElement>();\r\n\r\n const data = reactive<Data>({\r\n /**\r\n * 是否显示\r\n *\r\n * @type {Boolean}\r\n */\r\n show: true,\r\n /**\r\n * 偏移位置\r\n *\r\n * @type {Number}\r\n */\r\n offset: 0,\r\n /**\r\n * 延迟时间\r\n *\r\n * @type {Number}\r\n */\r\n duration: 0,\r\n /**\r\n * 是否挂载完成\r\n *\r\n * @type {Boolean}\r\n */\r\n mounted: null,\r\n /**\r\n * 内容外层宽度\r\n *\r\n * @type {Number}\r\n */\r\n contentWrapperWidth: 0,\r\n /**\r\n * 内容宽度\r\n *\r\n * @type {Number}\r\n */\r\n contentWidth: 0,\r\n /**\r\n * 倒计时\r\n *\r\n * @type {Function}\r\n */\r\n startTimer: null,\r\n });\r\n\r\n // computed\r\n\r\n // 外层样式\r\n const wrapperClasses = computed(() => {\r\n return [\r\n prefixCls,\r\n {\r\n [`${prefixCls}-wrapable`]: props.wrapable,\r\n },\r\n ];\r\n });\r\n\r\n const wrapperStyles = computed(() => {\r\n return {\r\n ...setBackgroundColor(props.background),\r\n ...setTextColor(props.textColor),\r\n };\r\n });\r\n\r\n // 文字样式\r\n const textStyles = computed(() => {\r\n return {\r\n transform: data.offset ? `translateX(${data.offset}px)` : '',\r\n transitionDuration: `${data.duration}s`,\r\n };\r\n });\r\n\r\n // 文字样式\r\n const textClasses = computed(() => {\r\n return [\r\n `${prefixCls}-text`,\r\n {\r\n [`${prefixCls}-text--ellipsis`]:\r\n props.scrollable === false && !props.wrapable,\r\n },\r\n ];\r\n });\r\n\r\n // methods\r\n\r\n // 设置背景颜色\r\n const setBackgroundColor = (color: string | any[]) => {\r\n let style = {};\r\n\r\n // 是否是数组\r\n if (Array.isArray(color)) {\r\n style = {\r\n background: `linear-gradient(135deg,${color[0]} 0%, ${color[1]} 100%)`,\r\n };\r\n } else if (isCssColor(color)) {\r\n style = {\r\n 'background-color': `${color}`,\r\n };\r\n }\r\n\r\n return style;\r\n };\r\n\r\n // 设置文字颜色\r\n const setTextColor = (color: string) => {\r\n let style = {};\r\n\r\n if (isCssColor(color)) {\r\n style = {\r\n color: `${color}`,\r\n };\r\n }\r\n\r\n return style;\r\n };\r\n\r\n // 初始化数据\r\n const reset = () => {\r\n const { delay, speed, scrollable } = props;\r\n\r\n // 是否有定义 delay\r\n const delayTime = isDef(delay) ? +delay * 1000 : 0;\r\n\r\n data.contentWrapperWidth = 0;\r\n data.contentWidth = 0;\r\n\r\n // 清除定时器\r\n clearTimeout(data.startTimer);\r\n\r\n // 动画延迟时间\r\n data.startTimer = setTimeout(() => {\r\n if (!contentWrapper.value || !content.value || scrollable === false) {\r\n return;\r\n }\r\n\r\n // 内容外层宽度\r\n const contentWrapperWidth =\r\n contentWrapper.value.getBoundingClientRect().width;\r\n // 内容宽度\r\n const contentWidth = content.value.getBoundingClientRect().width;\r\n\r\n // 是否开启滚动播放 || 内容长度溢出时默认开启\r\n if (scrollable || contentWidth > contentWrapperWidth) {\r\n doubleRaf(() => {\r\n data.contentWrapperWidth = contentWrapperWidth;\r\n data.contentWidth = contentWidth;\r\n\r\n data.offset = -contentWidth;\r\n data.duration = contentWidth / +speed;\r\n });\r\n }\r\n }, delayTime);\r\n };\r\n\r\n // 动画结束\r\n const handleTransitionEnd = () => {\r\n // 重制偏移位置\r\n data.offset = data.contentWrapperWidth;\r\n\r\n // 运动时间\r\n data.duration = 0;\r\n\r\n // 使用requestAnimationFrame\r\n raf(() => {\r\n // 使用双 raf 确保动画可以开始\r\n doubleRaf(() => {\r\n // 重新设置偏移位置\r\n data.offset = -data.contentWidth;\r\n // 重新设置运动时间\r\n data.duration =\r\n (data.contentWidth + data.contentWrapperWidth) / +props.speed;\r\n\r\n // 每当滚动栏重新开始滚动时触发\r\n emit('on-replay');\r\n });\r\n });\r\n };\r\n\r\n // 关闭\r\n const handleClose = () => {\r\n data.show = false;\r\n\r\n emit('on-close');\r\n };\r\n\r\n // link\r\n const handleLink = () => {\r\n emit('on-link');\r\n };\r\n\r\n // watch\r\n\r\n // 监听文字 | 是否开启滚动播放\r\n watch(() => [props.text, props.scrollable], reset);\r\n\r\n // onMounted\r\n onMounted(() => {\r\n reset();\r\n\r\n // 当一条会话历史记录被执行的时候将会触发页面显示\r\n on(window, 'pageshow', reset);\r\n\r\n nextTick(() => {\r\n data.mounted = true;\r\n });\r\n });\r\n\r\n // onActivated\r\n onActivated(() => {\r\n if (data.mounted) {\r\n reset();\r\n\r\n // 当一条会话历史记录被执行的时候将会触发页面显示\r\n on(window, 'pageshow', reset);\r\n }\r\n });\r\n\r\n // onUnmounted\r\n onUnmounted(() => {\r\n // 当一条会话历史记录被执行的时候将会触发页面显示\r\n off(window, 'pageshow', reset);\r\n });\r\n\r\n // onDeactivated\r\n onDeactivated(() => {\r\n // 当一条会话历史记录被执行的时候将会触发页面显示\r\n off(window, 'pageshow', reset);\r\n });\r\n\r\n return {\r\n prefixCls,\r\n\r\n // dom\r\n contentWrapper,\r\n content,\r\n\r\n // data\r\n data,\r\n\r\n // computed\r\n textStyles,\r\n textClasses,\r\n wrapperClasses,\r\n wrapperStyles,\r\n\r\n // methods\r\n reset,\r\n handleTransitionEnd,\r\n handleClose,\r\n handleLink,\r\n };\r\n },\r\n components: {\r\n IvueIcon,\r\n },\r\n});\r\n</script>\r\n"],"names":["_withDirectives","_openBlock","_createElementBlock","_normalizeClass","_normalizeStyle","_createCommentVNode","_createElementVNode","_renderSlot"],"mappings":";;;;;;gDACE,WAuCM,CAAA,CAAA;AAvC6B,EAAA,OAAAA,cAAA,EAAAC,SAAA,EAAe,EAAAC,kBAAA,CAAA,KAAA,EAAA;AAAA,IAAA,KAAA,EAAAC,cAAA,CAAA,IAAA,CAAA,cAAA,CAAA;AAAA,IAChD,KAAA,EAAaC,cAAA,CAAA,IAAA,CAAA,aAAA,CAAA;AAAA,GACb,EAAA;AAAA,IAAAC,mBAAW,QAAK,CAAA;AAAA,IAAAC,mBAAA,KAAA,EAAA;AAAA,MACd,KAIO,EAAAH,cAAA,CAAA,CAAA,EAAA,IAAA,CAAA,SAAA,CAAA,KAAA,CAAA,CAAA;AAAA,KAAA,EAAA;AAAA,8BAHL,UAEc,EAAA,IAAA,MAAA;AAAA,QAAA,IAAA,CAAA,QAAA,IAAAF,SAFG,EAAA,cAAK,oBAAS,EAAA;AAAA,UAAA,GAAA,EAAA,CAAA;AAAA,UAE7B,KAAA,EAAAE,cAAA,CAAA,CAAA,EAAA,IAAA,CAAA,SAAA,CAAA,KAAA,CAAA,CAAA;AAAA,SAAA,EAAA;AAAA;;;;;OAGN,CAAA;AAAA,OACA,CAAA,CAAA;AAAA,IAAWE,mBAAA,gBAAA,CAAA;AAAA,IAAAC,mBAAoC,KAAgB,EAAA;AAAA,MAAA,KAAA,EAAAH,cAAA,CAAA,CAAA,EAAA,IAAA,CAAA,SAAA,CAAA,cAAA,CAAA,CAAA;AAAA,MAC7D,GAAA,EAAA,gBAAA;AAAA,KAAA,EAAA;AAAA,yBAEQ,KAAE,EAAA;AAAA,QACP,KAAA,EAAiBA,cAAA,CAAA,IAAA,CAAA,WAAA,CAAA;AAAA,QAClB,KAAA,EAAIC,cAAS,CAAA,IAAA,CAAA,UAAA,CAAA;AAAA,QAAA,iBAAA,IAAA,CAAA,mBAAA;AAAA,QAEb,GAAA,EAAA,SAAA;AAAA,OAAA,EAAA;AAAA;;;OAGJ,EAAa,IAAA,UAAA,CAAA;AAAA,OACb,CAAA,CAAA;AAAA,IAAAC,mBAAW,QAAK,CAAA;AAAA,IAAAC,mBAAA,KAAA,EAAA;AAAA,MACd,KAeO,EAAAH,cAAA,CAAA,CAAA,EAAA,IAAA,CAAA,SAAA,CAAA,MAAA,CAAA,CAAA;AAAA,KAAA,EAAA;AAAA,MAVOI,WAAA,IAAA,CAAA,MAAA,EAAA,UAAA,EAAA,IAAA,MAAA;AAAA,QAHZF,mBAAA,4BAAA,CAAA;AAAA,QAAA,KAAA,IAAA,KAAA,WAAA,IAAAJ,SACQ,EAAA,cAAK,oBAAS,EAAA;AAAA,UACnB,GAAA,EAAA,CAAA;AAAA,UAAA,KAAA,EAAAE,cAAA,CAAA,CAAA,EAAA,IAAA,CAAA,SAAA,CAAA,KAAA,CAAA,CAAA;AAAA;;;;;;SAIH,EAAA,GAAA,CAAA,OAAA,EAAa,eAILE,kBAAI,CAAA,MAAA,EAAA,IAAA,CAAA;AAAA,QAHZA,mBAAA,4BAAA,CAAA;AAAA,QAAA,KAAA,IAAA,KAAA,MAAA,IAAAJ,SACQ,EAAA,cAAK,oBAAS,EAAA;AAAA,UACnB,GAAA,EAAA,CAAA;AAAA,UAAA,KAAA,EAAAE,cAAA,CAAA,CAAA,EAAA,IAAA,CAAA,SAAA,CAAA,KAAA,CAAA,CAAA;AAAA;;;;;;;;OAjCmD,CAAA,CAAA;AAAA,GAAA,EAAA,CAAA,CAAA,GAAA;AAAA;;;;;;;"}