wd-grid.vue 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. <template>
  2. <view :class="`wd-grid ${customClass}`" :style="rootStyle">
  3. <!-- 默认插入的 item -->
  4. <slot />
  5. </view>
  6. </template>
  7. <script lang="ts">
  8. export default {
  9. name: 'wd-grid',
  10. options: {
  11. virtualHost: true,
  12. addGlobalClass: true,
  13. styleIsolation: 'shared'
  14. }
  15. }
  16. </script>
  17. <script lang="ts" setup>
  18. import { computed, watch } from 'vue'
  19. import { useChildren } from '../composables/useChildren'
  20. import { GRID_KEY, gridProps } from './types'
  21. import { debounce } from '../common/util'
  22. const nextTick = () => new Promise((resolve) => setTimeout(resolve, 20))
  23. const props = defineProps(gridProps)
  24. // 子元素个数
  25. const { linkChildren, children } = useChildren(GRID_KEY)
  26. linkChildren({ props })
  27. watch(
  28. () => props.column,
  29. (val, oldVal) => {
  30. if (val === oldVal) return
  31. if (!val || val <= 0) {
  32. console.error(
  33. 'The number of columns attribute value is invalid. The attribute must be greater than 0 and it is not recommended to use a larger value attribute.'
  34. )
  35. }
  36. oldVal && init()
  37. },
  38. {
  39. deep: true,
  40. immediate: true
  41. }
  42. )
  43. watch(
  44. () => props.border,
  45. (val) => {
  46. val &&
  47. Promise.resolve()
  48. .then(nextTick)
  49. .then(() => {
  50. init()
  51. })
  52. },
  53. {
  54. deep: true,
  55. immediate: true
  56. }
  57. )
  58. watch(
  59. () => children,
  60. () => {
  61. handleChildrenChange()
  62. },
  63. {
  64. deep: true
  65. }
  66. )
  67. const rootStyle = computed(() => {
  68. return `${props.gutter ? 'padding-left:' + props.gutter + 'px;' + 'padding-bottom:' + props.gutter + 'px;' : ''}${props.customStyle}`
  69. })
  70. const handleChildrenChange = debounce(() => {
  71. init()
  72. }, 50)
  73. function init() {
  74. if (!children) return
  75. children.forEach((item, index) => {
  76. if (props.border) {
  77. const { column } = props
  78. if (column) {
  79. const isRightItem = children.length - 1 === index || (index + 1) % column === 0
  80. const isFirstLine = index + 1 <= column
  81. isFirstLine && item.$.exposed!.setiIemClass('is-first')
  82. isRightItem && item.$.exposed!.setiIemClass('is-right')
  83. !isFirstLine && item.$.exposed!.setiIemClass('is-border')
  84. } else {
  85. item.$.exposed!.setiIemClass('is-first')
  86. }
  87. children.length - 1 === index && item.$.exposed!.setiIemClass(item.$.exposed!.itemClass.value + ' is-last')
  88. }
  89. item.$.exposed!.init()
  90. })
  91. }
  92. </script>
  93. <style lang="scss" scoped>
  94. @import './index.scss';
  95. </style>