v-ellipsis.ts 3.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. // v-ellipsis.ts
  2. import { createApp, ref } from 'vue'
  3. import 'uview-plus/index.scss' // 若使用 uView Plus,需要导入
  4. export default {
  5. mounted(el: HTMLElement, binding: any) {
  6. const { value } = binding
  7. const line = value?.lines ?? 1
  8. const content = value?.content ?? el.innerText
  9. // 省略号默认样式
  10. el.style.display = '-webkit-box'
  11. el.style.webkitBoxOrient = 'vertical'
  12. el.style.overflow = 'hidden'
  13. el.style.textOverflow = 'ellipsis'
  14. el.style.webkitLineClamp = String(line)
  15. el.style.cursor = 'pointer'
  16. el.style.wordBreak = 'break-all'
  17. let pressTimer: any = null
  18. // 创建 u-popup 的 Vue 子应用
  19. const popupApp = createApp({
  20. setup() {
  21. const show = ref(false)
  22. const position = ref({ top: 0, left: 0 })
  23. return { show, position, content }
  24. },
  25. template: `
  26. <u-popup
  27. v-model="show"
  28. mode="center"
  29. :custom-style="{
  30. position: 'absolute',
  31. top: position.top + 'px',
  32. left: position.left + 'px',
  33. background: '#333',
  34. color: '#fff',
  35. padding: '12px',
  36. borderRadius: '8px',
  37. maxWidth: '80vw',
  38. fontSize: '14px',
  39. lineHeight: '1.6',
  40. }"
  41. :mask="false"
  42. >
  43. {{ content }}
  44. </u-popup>
  45. `,
  46. })
  47. const container = document.createElement('div')
  48. document.body.appendChild(container)
  49. const popupInstance = popupApp.mount(container) as any
  50. const showPopup = (event: MouseEvent | TouchEvent) => {
  51. if (!popupInstance?.position || !popupInstance?.show) return
  52. const rect = el.getBoundingClientRect()
  53. popupInstance.position.top = rect.top - 10
  54. popupInstance.position.left = rect.left + rect.width / 2
  55. popupInstance.show = true
  56. }
  57. const hidePopup = () => {
  58. if (popupInstance?.show !== undefined) popupInstance.show = false
  59. }
  60. // PC hover 事件
  61. el.addEventListener('mouseenter', showPopup)
  62. el.addEventListener('mouseleave', hidePopup)
  63. // mobile 长按显示
  64. el.addEventListener('touchstart', (e) => {
  65. pressTimer = setTimeout(() => showPopup(e), 600)
  66. })
  67. el.addEventListener('touchend', () => {
  68. clearTimeout(pressTimer)
  69. hidePopup()
  70. })
  71. el.addEventListener('touchmove', () => {
  72. clearTimeout(pressTimer)
  73. hidePopup()
  74. })
  75. el._ellipsis_destroy = () => {
  76. popupApp.unmount()
  77. container.remove()
  78. el.removeEventListener('mouseenter', showPopup)
  79. el.removeEventListener('mouseleave', hidePopup)
  80. }
  81. },
  82. unmounted(el: any) {
  83. el._ellipsis_destroy && el._ellipsis_destroy()
  84. },
  85. }