ivue-material-plus
Version:
A high quality UI components Library with Vue.js
1 lines • 16 kB
Source Map (JSON)
{"version":3,"file":"index2.mjs","sources":["../../../../../src/components/ivue-ellipsis/index.vue"],"sourcesContent":["<template>\r\n <div :class=\"prefixCls\" ref=\"wrapper\">\r\n <template v-if=\"data.computedReady\">\r\n <!-- tooltip -->\r\n <ivue-tooltip\r\n :class=\"`${prefixCls}-tooltip--wrapper`\"\r\n :content=\"text\"\r\n :placement=\"placement\"\r\n :theme=\"theme\"\r\n :transfer=\"transfer\"\r\n :maxWidth=\"maxWidth\"\r\n v-if=\"tooltip\"\r\n >\r\n <span :class=\"`${prefixCls}-tooltip`\">\r\n <!-- text -->\r\n <span :class=\"`${prefixCls}-text`\" ref=\"textRef\">{{ text }}</span>\r\n <!-- oversize -->\r\n <span\r\n :class=\"`${prefixCls}-more`\"\r\n v-show=\"data.oversize\"\r\n ref=\"moreRef\"\r\n >\r\n <slot name=\"more\">...</slot>\r\n </span>\r\n <!-- suffix -->\r\n <slot name=\"suffix\"></slot>\r\n </span>\r\n </ivue-tooltip>\r\n <!-- 普通显示 -->\r\n <template v-else>\r\n <!-- text -->\r\n <span :class=\"`${prefixCls}-text`\" ref=\"textRef\">{{ text }}</span>\r\n <!-- oversize -->\r\n <span :class=\"`${prefixCls}-more`\" v-show=\"data.oversize\" ref=\"moreRef\">\r\n <slot name=\"more\">...</slot>\r\n </span>\r\n <!-- suffix -->\r\n <slot name=\"suffix\"></slot>\r\n </template>\r\n </template>\r\n <!-- 站位节点 -->\r\n <div :class=\"`${prefixCls}-hidden`\" v-else>\r\n <!-- text -->\r\n <span :class=\"`${prefixCls}-text`\" ref=\"textRef\">{{ text }}</span>\r\n <!-- oversize -->\r\n <span :class=\"`${prefixCls}-more`\" v-show=\"data.oversize\" ref=\"moreRef\">\r\n <slot name=\"more\">...</slot>\r\n </span>\r\n <!-- suffix -->\r\n <slot name=\"suffix\"></slot>\r\n </div>\r\n </div>\r\n</template>\r\n\r\n<script lang=\"ts\">\r\nimport {\r\n defineComponent,\r\n onMounted,\r\n reactive,\r\n ref,\r\n watch,\r\n nextTick,\r\n getCurrentInstance,\r\n} from 'vue';\r\nimport { useEventListener } from '@vueuse/core';\r\n\r\n// utils\r\nimport { oneOf } from '../../utils/assist';\r\nimport { getStyle } from '../../utils/assist';\r\n\r\nimport IvueTooltip from '../ivue-tooltip';\r\n\r\n// type\r\nimport type { Props, Data } from './types/ellipsis';\r\n\r\nconst prefixCls = 'ivue-ellipsis';\r\n\r\nexport default defineComponent({\r\n name: prefixCls,\r\n emits: ['on-hide', 'on-show'],\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 * 按照指定长度截取\r\n *\r\n * @type {Number}\r\n */\r\n length: {\r\n type: Number,\r\n },\r\n /**\r\n * 限制的高度\r\n *\r\n * @type {Number}\r\n */\r\n height: {\r\n type: Number,\r\n },\r\n /**\r\n * 是否禁用省略\r\n *\r\n * @type {Boolean}\r\n */\r\n disabled: {\r\n type: Boolean,\r\n default: false,\r\n },\r\n /**\r\n * 限制行数,将换算为 height。如果设置了 height,则直接使用 height 计算\r\n *\r\n * @type {Number}\r\n */\r\n lines: {\r\n type: Number,\r\n },\r\n /**\r\n * 是否将全角字符的长度视为2来计算字符串长度,适用于 length\r\n *\r\n * @type {Boolean}\r\n */\r\n fullWidthRecognition: {\r\n type: Boolean,\r\n default: false,\r\n },\r\n /**\r\n * 是否自动根据外层宽度动态改变 (设置 height 时生效)\r\n *\r\n * @type {Boolean}\r\n */\r\n autoResize: {\r\n type: Boolean,\r\n default: true,\r\n },\r\n /**\r\n * 是否开启 tooltip\r\n *\r\n * @type {Boolean}\r\n */\r\n tooltip: {\r\n type: Boolean,\r\n default: false,\r\n },\r\n /**\r\n * 弹窗的展开方向\r\n *\r\n * @type {String}\r\n */\r\n placement: {\r\n type: String,\r\n validator(value: string) {\r\n return oneOf(value, [\r\n 'top',\r\n 'top-start',\r\n 'top-end',\r\n 'bottom',\r\n 'bottom-start',\r\n 'bottom-end',\r\n 'left',\r\n 'left-start',\r\n 'left-end',\r\n 'right',\r\n 'right-start',\r\n 'right-end',\r\n ]);\r\n },\r\n default: 'bottom',\r\n },\r\n /**\r\n * 主题,可选值为 dark 或 light\r\n *\r\n * @type {String}\r\n */\r\n theme: {\r\n type: String,\r\n validator(value: string) {\r\n return oneOf(value, ['dark', 'light']);\r\n },\r\n default: 'dark',\r\n },\r\n /**\r\n * 是否将弹层放置于 body 内,在 Tabs、\r\n * 带有 fixed 的 Table 列内使用时,\r\n * 建议添加此属性,它将不受父级样式影响,\r\n * 从而达到更好的效果\r\n *\r\n * @type {Boolean}\r\n */\r\n transfer: {\r\n type: Boolean,\r\n default() {\r\n const global = getCurrentInstance().appContext.config.globalProperties;\r\n\r\n return !global.$IVUE || global.$IVUE.transfer === ''\r\n ? false\r\n : global.$IVUE.transfer;\r\n },\r\n },\r\n /**\r\n * 最大宽度,超出最大值后,文本将自动换行,并两端对齐\r\n *\r\n * @type {String, Number}\r\n */\r\n maxWidth: {\r\n type: [String, Number],\r\n },\r\n },\r\n setup(props: Props, { emit }) {\r\n // dom\r\n const wrapper = ref<HTMLDivElement>();\r\n const textRef = ref<HTMLSpanElement>();\r\n const moreRef = ref<HTMLSpanElement>();\r\n\r\n // data\r\n const data = reactive<Data>({\r\n /**\r\n * 先隐形计算,计算好后,再根据配置显示\r\n *\r\n * @type {Boolean}\r\n */\r\n computedReady: false,\r\n /**\r\n * 计算后显示的text\r\n *\r\n * @type {String}\r\n */\r\n computedText: '',\r\n /**\r\n * 超出长度\r\n *\r\n * @type {Boolean}\r\n */\r\n oversize: false,\r\n });\r\n\r\n // methods\r\n\r\n // 初始化\r\n const init = () => {\r\n // 禁用\r\n if (!props.disabled) {\r\n // 计算显示的text\r\n setShowText();\r\n // 超出显示\r\n limitShow();\r\n }\r\n // 禁用显示未省略\r\n else {\r\n data.computedReady = true;\r\n }\r\n };\r\n\r\n // 计算显示的text\r\n const setShowText = () => {\r\n // 初始化状态\r\n data.oversize = false;\r\n // 先隐形计算,计算好后,再根据配置显示\r\n data.computedReady = false;\r\n\r\n nextTick(() => {\r\n const $wrapper = wrapper.value;\r\n const $more = moreRef.value;\r\n\r\n // 限制的高度\r\n let height = props.height;\r\n // 文本\r\n let text = props.text;\r\n\r\n // 当 height 未定义,且 lines 定义时,计算真实高度,否则使用 限制的高度\r\n if (!props.height && props.lines) {\r\n // 行高\r\n const lineHeight = parseInt(getStyle($wrapper, 'lineHeight'), 10);\r\n\r\n // 行高 * 限制行数\r\n height = lineHeight * props.lines;\r\n }\r\n\r\n // 有textRef\r\n // 指定 length,则按具体字数剪裁\r\n if (props.length) {\r\n const textLength = props.fullWidthRecognition\r\n ? getStrFullLength(text)\r\n : text.length;\r\n\r\n // 超出指定长度截取\r\n if (textLength > props.length) {\r\n // 超出长度\r\n data.oversize = true;\r\n $more.style.display = 'inline-block';\r\n\r\n // 计算后显示的text\r\n text = props.fullWidthRecognition\r\n ? cutStrLength(text, props.length)\r\n : text.slice(0, props.length);\r\n }\r\n\r\n // 计算后显示的text\r\n data.computedText = text;\r\n }\r\n // 指定高度\r\n else {\r\n specifiedHeight(height);\r\n }\r\n });\r\n };\r\n\r\n // 指定高度\r\n const specifiedHeight = (height: number) => {\r\n const $wrapper = wrapper.value;\r\n const $more = moreRef.value;\r\n const $text = textRef.value;\r\n\r\n // 文本\r\n let text = props.text;\r\n\r\n // 最大执行次数\r\n let n = 1000;\r\n\r\n // offsetHeight > 设置的高度\r\n if ($wrapper.offsetHeight > height) {\r\n // 超出长度\r\n data.oversize = true;\r\n\r\n $more.style.display = 'inline-block';\r\n\r\n while ($wrapper.offsetHeight > height && n > 0) {\r\n if ($wrapper.offsetHeight > height * 3) {\r\n text = text.substring(0, Math.floor(text.length / 2));\r\n\r\n $text.innerText = text;\r\n } else {\r\n text = text.substring(0, text.length - 1);\r\n\r\n $text.innerText = text;\r\n }\r\n\r\n n--;\r\n }\r\n }\r\n\r\n // 没有开启自动根据外层宽度动态改变\r\n if (!props.autoResize) {\r\n // 计算后显示的text\r\n data.computedText = text;\r\n }\r\n };\r\n\r\n // 超出显示\r\n const limitShow = () => {\r\n data.computedReady = true;\r\n\r\n nextTick(() => {\r\n if (textRef.value) {\r\n // 文本省略的时候触发\r\n if (wrapper.value.offsetHeight > props.height) {\r\n emit('on-hide');\r\n }\r\n // 文本全部展示的时候触发\r\n else {\r\n emit('on-show');\r\n }\r\n }\r\n });\r\n };\r\n\r\n // 获取字符串全部长度\r\n const getStrFullLength = (str = '') => {\r\n return str.split('').reduce((pre, cur) => {\r\n // 字符在字符串中的下标->第一个\r\n const charCode = cur.charCodeAt(0);\r\n\r\n // 前 128 ASCII 字符编码\r\n if (charCode >= 0 && charCode <= 128) {\r\n return pre + 1;\r\n }\r\n\r\n return pre + 2;\r\n }, 0);\r\n };\r\n\r\n // 切割字符串\r\n const cutStrLength = (str = '', maxLength: number) => {\r\n let showLength = 0;\r\n\r\n return str.split('').reduce((pre, cur) => {\r\n // 字符在字符串中的下标->第一个\r\n const charCode = cur.charCodeAt(0);\r\n\r\n // 前 128 ASCII 字符编码\r\n if (charCode >= 0 && charCode <= 128) {\r\n showLength += 1;\r\n }\r\n // 不是前 128 ASCII 字符编码\r\n else {\r\n showLength += 2;\r\n }\r\n\r\n // 设置长度\r\n if (showLength <= maxLength) {\r\n return pre + cur;\r\n }\r\n\r\n return pre;\r\n }, '');\r\n };\r\n\r\n // 自适应高度\r\n const autoResizeHeight = () => {\r\n // 已经显示文本 && 有设置高度\r\n if (data.computedReady && props.height) {\r\n // 限制的高度\r\n const height = props.height;\r\n // 文本\r\n const text = props.text;\r\n\r\n // 重新设置文本\r\n textRef.value.innerText = text;\r\n\r\n // 指定高度\r\n specifiedHeight(height);\r\n }\r\n };\r\n\r\n // 设置文本节点文本\r\n const setTextInnerText = () => {\r\n // 计算后显示的text\r\n textRef.value.innerText = data.computedText;\r\n };\r\n\r\n // watch\r\n\r\n // 监听计算后显示的text\r\n watch(\r\n () => data.computedText,\r\n (value) => {\r\n if (value) {\r\n data.computedReady = true;\r\n\r\n // 设置文本节点文本\r\n setTextInnerText();\r\n }\r\n }\r\n );\r\n\r\n // 监听按照指定长度截取\r\n watch(\r\n () => props.length,\r\n () => {\r\n init();\r\n }\r\n );\r\n\r\n // 监听限制的高度\r\n watch(\r\n () => props.height,\r\n () => {\r\n init();\r\n }\r\n );\r\n\r\n // 监听是否禁用省略\r\n watch(\r\n () => props.disabled,\r\n () => {\r\n init();\r\n }\r\n );\r\n\r\n // 监听限制行数\r\n watch(\r\n () => props.lines,\r\n () => {\r\n init();\r\n }\r\n );\r\n\r\n // onMounted\r\n onMounted(() => {\r\n // 初始化\r\n init();\r\n\r\n // 是否自动根据外层宽度动态改变\r\n if (props.autoResize && props.height) {\r\n // window resize\r\n useEventListener('resize', autoResizeHeight);\r\n }\r\n });\r\n\r\n return {\r\n prefixCls,\r\n\r\n // dom\r\n wrapper,\r\n textRef,\r\n moreRef,\r\n\r\n // data\r\n data,\r\n };\r\n },\r\n components: {\r\n IvueTooltip,\r\n },\r\n});\r\n</script>\r\n"],"names":["_resolveComponent","_openBlock","_createElementBlock","_normalizeClass","_Fragment","_createCommentVNode","_withCtx","_createElementVNode","_toDisplayString","_withDirectives","_vShow"],"mappings":"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"}