Browse Source

Merge branch 'dev' of https://git.citupro.com/zhengnaiwen_citu/menduner into dev

Xiao_123 3 months ago
parent
commit
aeab897891

+ 2 - 2
src/components/Ellipsis/index.vue

@@ -85,8 +85,8 @@ function updateTooltipShow() {
   const clientWidth = ellipsisRef.value.clientWidth
   const clientHeight = ellipsisRef.value.clientHeight
   const offsetWidth = ellipsisRef.value.offsetWidth
-  // computedTooltipMaxWidth.value = `${offsetWidth + 24}px`
-  computedTooltipMaxWidth.value = `100vw`
+  computedTooltipMaxWidth.value = `${offsetWidth + 24}px`
+  // computedTooltipMaxWidth.value = `100vw`
   if (scrollWidth > clientWidth || scrollHeight > clientHeight) {
     if (props.expand) {
       showExpand.value = true

File diff suppressed because it is too large
+ 0 - 0
src/components/Enterprise/hotPromoted.vue


+ 3 - 2
src/components/Tooltip/index.vue

@@ -15,7 +15,7 @@ import {
 const props = defineProps({
   maxWidth: { // 文本最大宽度,单位 px
     type: [String, Number],
-    default: 100
+    default: 240
   },
   content: { // 展示的内容 string | slot
     type: String,
@@ -252,7 +252,8 @@ async function getPosition() {
   }
   if (['top', 'bottom'].includes(tooltipPlace.value)) {
     top.value = tooltipCardHeight.value + (props.arrow ? 4 + 12 : 6)
-    left.value = ((tooltipCardWidth.value - contentWidth.value) / 2) + contentWidth.value.offsetLeft
+    // left.value = ((tooltipCardWidth.value - contentWidth.value) / 2) + contentWidth.value.offsetLeft
+    left.value = (tooltipCardWidth.value - contentWidth.value) / 2
   } else {
     top.value = (tooltipCardHeight.value - contentHeight.value) / 2
     left.value = tooltipCardWidth.value + (props.arrow ? 4 + 12 : 6)

+ 189 - 0
src/directives/ellipsisTooltip/index.js

@@ -0,0 +1,189 @@
+/* 
+    文档来源 https://blog.csdn.net/weixin_41277748/article/details/138855857
+    代码来源 https://github.com/DearWQ/wq-admin-system/blob/main/src/directive/toolTip/MyToolTip.vue
+*/
+
+// 引入组件
+import {createApp, nextTick} from "vue";
+import MyToolTip from './index.vue'
+
+function getViewportSize() {
+    return {
+        windowWidth: window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth,
+        windowHeight: window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight
+    };
+}
+
+let windowWidth = getViewportSize().windowWidth
+let windowHeight = getViewportSize().windowHeight
+
+
+
+// 位置定位
+function calculationLocation(el, target, placements) {
+    if (!el || !target) return;
+    el.tooltipPosition.y = 0;
+    el.tooltipPosition.x = 0;
+    // @ts-ignore
+    let el_dom = target.w_tooltip.firstElementChild.getBoundingClientRect()
+    let target_dom = target.getBoundingClientRect()
+    if (placements === "left") {
+        el.tooltipPosition.x = 0
+        el.tooltipPosition.y = target_dom.y - target_dom.height / 2
+        el.tooltipPosition.right = windowWidth - target_dom.left + target_dom.height / 2
+    } else if (placements === "left-right") {
+        el.tooltipPosition.x = 0
+        el.tooltipPosition.y = target_dom.y - (el_dom?.height || 0) / 2 + target_dom.height / 2
+        el.tooltipPosition.left = target_dom.left + target_dom.width + 10
+    } else if (placements === "bottom") {
+        el.tooltipPosition.x = target_dom.x + target_dom.width / 2 - (el_dom?.width || 0) / 2
+        el.tooltipPosition.y = target_dom.y + target_dom.height + 10
+        if (el.tooltipPosition.x > (windowWidth-el_dom.width) && target_dom.left + el_dom.width > windowWidth) {
+            el.tooltipPosition.x = windowWidth - el_dom.width
+            el.arrowPosition.left = (el_dom.width / 10) * 8
+        }
+        if (el.tooltipPosition.x < 0) {
+            el.arrowPosition.left = (el_dom.width / 10) * 2
+        }
+
+    } else if (placements === "right") {
+        el.tooltipPosition.x = 0
+        el.tooltipPosition.y = target_dom.y - (el_dom?.height || 0) / 2 + target_dom.height / 2
+        el.tooltipPosition.left = target_dom.left + target_dom.width + 10
+    } else if (placements === "right-left") {
+        //提示文字的位置
+        el.tooltipPosition.x = 0;
+        el.tooltipPosition.y = target_dom.y - target_dom.height / 2;
+        el.tooltipPosition.right = windowWidth - target_dom.left + target_dom.height / 2
+        //三角形的位置
+        el.arrowPosition.top = target_dom.height
+    } else if (placements === "top") {
+        el.tooltipPosition.x = target_dom.x + target_dom.width / 2 - (el_dom?.width || 0) / 2
+        el.tooltipPosition.y = target_dom.y - target_dom.height - 20
+        if (el.tooltipPosition.x > (windowWidth-el_dom.width) && target_dom.left + el_dom.width > windowWidth) {
+            el.tooltipPosition.x = windowWidth - el_dom.width
+            el.arrowPosition.left = (el_dom.width / 10) * 9
+        }
+        if (el.tooltipPosition.x < 0) {
+            el.arrowPosition.left = (el_dom.width / 10) * 2
+        }
+    }
+    el.tooltipPosition.x = el.tooltipPosition.x < 0 ? 0 : el.tooltipPosition.x
+    el.tooltipPosition.y = el.tooltipPosition.y < 0 ? 0 : el.tooltipPosition.y
+}
+
+/**
+ * 处理边界情况
+ * @param  {HTMLElement} el
+ * @param direction
+ * return {string} props
+ */
+function dealDomBoundary(el, direction) {
+    let target_dom = el.getBoundingClientRect()
+    //处理上下左右边界情况
+    if (target_dom.left < 150 && direction === 'left') {
+        direction = 'left-right'
+    }
+
+    if (target_dom.right > (windowWidth - 150) && direction === 'right') {
+        direction = 'right-left'
+    }
+    if (target_dom.top > windowHeight / 100 * 90 && direction === 'bottom') {
+        direction = 'top'
+    }
+    if (target_dom.top < windowHeight / 100 * 10 && direction === 'top') {
+        direction = 'bottom'
+    }
+    return direction
+}
+
+// 方向
+const allPlacements = ['left', 'bottom', 'right', 'top']
+
+
+function getElStyleAttr(element, attr) {
+    const styles = window.getComputedStyle(element)
+    // @ts-ignore
+    return styles[attr]
+}
+
+const isOverflow = (target) => {
+    const scrollWidth = target.scrollWidth
+    const offsetWidth = target.offsetWidth
+    const range = document.createRange()
+    range.setStart(target, 0)
+    range.setEnd(target, target.childNodes.length)
+    const rangeWidth = range.getBoundingClientRect().width
+    const padding = (parseInt(getElStyleAttr(target, 'paddingLeft'), 10) || 0) + (parseInt(getElStyleAttr(target, 'paddingRight'), 10) || 0)
+    return (rangeWidth + padding > target.offsetWidth) || scrollWidth > offsetWidth
+}
+
+export const ellipsisTooltip = localStorage.getItem('useEllipseTooltip') ? {
+    mounted(el, binding) {
+        //获取指令的参数
+        const {
+            value: {
+                placement, content, destroyOnLeave
+            } = {}
+        } = binding;
+        // 加上超出...样式
+        el.style.overflow = "hidden";
+        el.style.textOverflow = "ellipsis";
+        el.style.whiteSpace = "nowrap";
+        windowWidth = getViewportSize().windowWidth
+        windowHeight = getViewportSize().windowHeight
+        //鼠标移开时 清除元素
+        const onMouseLeave = () => {
+            if (el.w_tipInstance) {
+                el.w_tipInstance.hiddenTip()
+                el.w_tooltip.remove()
+                el.w_tipInstance = null
+                el.w_tooltip = null
+            }
+        };
+        const onMouseEnter = () => {
+            // 判断内容长度 需要展示
+            if (isOverflow(el)) {
+                // @ts-ignore
+                const directiveList = allPlacements.filter(placement => binding.modifiers[placement])
+                const placements = directiveList.length ? directiveList : allPlacements
+                if (!el.w_tooltip) {
+                    // 创建tooltip实例
+                    const vm = createApp(MyToolTip)
+                    // 创建根元素
+                    el.w_tooltip = document.createElement('div')
+                    // 挂载到页面
+                    document.body.appendChild(el.w_tooltip)
+                    el.w_tooltip.id = `tooltip_${Math.floor(Math.random() * 10000)}`
+                    el.w_tipInstance = vm.mount(el.w_tooltip)
+                }
+                // 设置 tooltip 显示方向 处理边界情况
+                let direction = dealDomBoundary(el, placement || placements[0] || 'top')
+
+                el.w_tipInstance.placements = direction;
+                // 设置显示内容
+                el.w_tipInstance.setContent(content || el.innerText)
+                // 使 tooltip 显示
+                el.w_tipInstance.showTip()
+                nextTick(() => {
+                    // 计算 tooltip 在页面中的位置
+                    calculationLocation(el.w_tipInstance, el, direction)
+                })
+                el._scrollHandler = () => {
+                    // 重新定位位置
+                    if (el.w_tipInstance) calculationLocation(el.w_tipInstance, el, placements[0])
+                }
+                window.addEventListener('scroll', el._scrollHandler)
+                const _destroyOnLeave = destroyOnLeave || true
+                if (_destroyOnLeave) el.addEventListener("mouseleave", onMouseLeave);
+            }
+        };
+        el.addEventListener("mouseenter", onMouseEnter);
+    },
+    unmounted(el) {
+        if (el.w_tooltip) {
+            document.body.removeChild(el.w_tooltip)
+        }
+        window.removeEventListener('scroll', el._scrollHandler)
+    }
+} : {}

+ 173 - 0
src/directives/ellipsisTooltip/index.vue

@@ -0,0 +1,173 @@
+<template>
+  <!--提示-->
+  <transition name="fade-in-linear">
+    <div v-show="tooltipShow" :style="tooltipStyle" class="wq-tooltip"
+    >
+      <span class="wq-tooltip-text" v-text="text"></span>
+      <div :class="[placements]" :style="arrowStyle" class="wq-tooltip-arrow"></div>
+    </div>
+  </transition>
+</template>
+<script>
+import {computed, ref} from 'vue'
+
+export default {
+  setup() {
+
+    // 显示弹框
+    const tooltipShow = ref(false);
+
+    // 提示内容
+    const text = ref()
+
+    // 方向
+    const placements = ref('left')
+
+    // 显示
+    function showTip() {
+      tooltipShow.value = true
+    }
+
+    //设置提示内容
+    function setContent(content) {
+      text.value = content
+    }
+
+    //隐藏
+    function hiddenTip() {
+      tooltipShow.value = false
+    }
+
+    // 位置
+    const tooltipPosition = ref({
+      x: 0,
+      y: 0,
+      width: 0,
+      left: 0,
+      top: 0,
+      right: 0,
+      bottom: 0,
+    })
+    const arrowPosition = ref({
+      left: 0,
+      top: 0,
+      right: 0,
+      bottom: 0,
+    })
+    const tooltipStyle = computed(() => {
+      return {
+        transform: `translate3d(${tooltipPosition.value.x}px,${tooltipPosition.value.y}px,0)`,
+        width: tooltipPosition.value.width ? `${tooltipPosition.value.width}px` : null,
+        right: tooltipPosition.value.right ? `${tooltipPosition.value.right}px` : null,
+        left: tooltipPosition.value.left ? `${tooltipPosition.value.left}px` : null,
+        top: tooltipPosition.value.top ? `${tooltipPosition.value.top}px` : null,
+      }
+    })
+    const arrowStyle = computed(() => {
+      return {
+        left: arrowPosition.value.left?`${arrowPosition.value.left}px` : null,
+        top: arrowPosition.value.top?`${arrowPosition.value.top}px` : null,
+        right: arrowPosition.value.right?`${arrowPosition.value.right}px` : null,
+        bottom: arrowPosition.value.bottom?`${arrowPosition.value.bottom}px` : null,
+      }
+    })
+    return {
+      tooltipShow,
+      showTip,
+      hiddenTip,
+      setContent,
+      tooltipPosition,
+      arrowPosition,
+      tooltipStyle,
+      arrowStyle,
+      text,
+      placements,
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+// tooltip
+.wq-tooltip {
+  padding: 10px;
+  font-size: 12px;
+  line-height: 1.2;
+  min-width: 30px;
+  max-width: fit-content;
+  word-wrap: break-word;
+  position: fixed;
+  top: 0;
+  background: #303133;
+  color: #fff;
+  z-index: 1000;
+  display: block;
+  border-radius: 8px;
+  font-weight: 500;
+  pointer-events: none;
+}
+
+// 小箭头
+.wq-tooltip-arrow {
+  position: absolute;
+  width: 0;
+  height: 0;
+  border-width: 8px;
+  border-style: solid;
+}
+
+// 如果在左侧
+.wq-tooltip-arrow.left {
+  border-color: transparent transparent transparent #303133;
+  right: -15px;
+  top: 50%;
+  transform: translate3d(0, -50%, 0);
+}
+.wq-tooltip-arrow.left-right {
+  left: -15px;
+  top: 50%;
+  transform: translate3d(0, -50%, 0);
+  border-color: transparent #303133 transparent transparent;
+}
+
+// 如果在下侧
+.wq-tooltip-arrow.bottom {
+  top: -15px;
+  border-color: transparent transparent #303133 transparent;
+  left: 50%;
+  transform: translate3d(-50%, 0, 0);
+}
+
+// 如果在右侧
+.wq-tooltip-arrow.right {
+  left: -15px;
+  top: 50%;
+  transform: translate3d(0, -50%, 0);
+  border-color: transparent #303133 transparent transparent;
+}
+.wq-tooltip-arrow.right-left {
+  border-color: transparent transparent transparent #303133;
+  right: -15px;
+  top: 50%;
+  transform: translate3d(0, -50%, 0);
+}
+// 如果在上侧
+.wq-tooltip-arrow.top {
+  bottom: -15px;
+  border-color: #303133 transparent transparent transparent;
+  left: 50%;
+  transform: translate3d(-50%, 0, 0);
+}
+
+/* 动画 */
+.tooltip-enter-from,
+.tooltip-leave-to {
+  opacity: 0;
+  transition: opacity .3s ease;
+}
+
+.tooltip-leave-from,
+.tooltip-enter-to {
+  transition: opacity .1s ease;
+}
+</style>

+ 2 - 1
src/main.js

@@ -31,7 +31,8 @@ import VueLuckyCanvas from '@lucky-canvas/vue'
 
 import router from './router'
 
-import { ellipsisTooltip } from '@/components/CtTooltip/index.js'
+// import { ellipsisTooltip } from '@/components/CtTooltip/index.js'
+import { ellipsisTooltip } from '@/directives/ellipsisTooltip/index.js'
 // import imageDirective from '@/directives/previewImageDirective'
 
 import './permission'

Some files were not shown because too many files changed in this diff