css3grid

grid表格

<template>
  <div
    class="grid-row"
    :class="getClass"
    :style="{ gridTemplateColumns: `repeat(${gridCols}, 1fr)` }"
    :rest="restDom"
    ref="divRef"
  >
    <template v-if="items.length">
      <cell-item
        v-for="(item, index) in items"
        :key="index"
        :label="item.name"
        :value="index"
      />
    </template>
    <slot v-else></slot>

    <template v-if="isShutt && (restDom || restCumput)">
      <div
        class="grid-col"
        v-for="(_item, index) in restDom || restCumput"
        :key="index"
      >
        <div class="label"></div>
        <div class="content"></div>
      </div>
    </template>
  </div>
</template>
<script setup>
import CellItem from './item.vue'
const props = defineProps({
  items: {
    type: Array,
    default: []
  },
  // 一行展示的数量,默认是3
  gridCols: {
    type: Number,
    default: 3
  },
  //是否需要补未满的单元格
  isShutt: {
    type: Boolean,
    default: true
  }
})

const divRef = ref(null)
const restDom = ref(0)

const resultAuto = computed(() => {
  return Array(props.gridCols).fill('auto').join(' ')
})

// props.gridCols.split(" ").filter(Boolean).length;

// 子节点[cell-item]单独渲染补位
function updateLiCount() {
  nextTick(() => {
    const count = divRef.value.querySelectorAll('.grid-row .base-col').length
    const mod = count % props.gridCols
    if (mod) {
      restDom.value = props.gridCols - mod
    }
  })
}

// 父节点[table-cell]循环渲染补位
const restCumput = computed(() => {
  const count = props.items.length
  const mod = count % props.gridCols
  if (mod) {
    return props.gridCols - mod
  }
  return 0
})

const getClass = computed(() => {
  const className = +props.gridCols
  return `last-${className}`
})

onUpdated(() => {
  updateLiCount()
})
</script>

<style lang="scss">
.grid {
  &-row {
    display: grid;
    /* grid-template-columns: v-bind(gridCols); */
    border-left: 1px solid rgba(216, 216, 216, 1);
    border-top: 1px solid rgba(216, 216, 216, 1);
    &.last-1 .grid-col {
      &:nth-last-child(-n + 1) {
        /* border-bottom: 0; */
      }
    }
    &.last-2 .grid-col {
      &:nth-last-child(-n + 2) {
        /* border-bottom: 0; */
      }
    }
    &.last-3 .grid-col {
      &:nth-last-child(-n + 3) {
        /* border-bottom: 0; */
      }
    }
    &.last-4 .grid-col {
      &:nth-last-child(-n + 4) {
        /* border-bottom: 0; */
      }
    }
  }
  &-col {
    background-color: rgba(255, 255, 255, 0.8);
    text-align: center;
    font-size: 30px;
    border-right: 1px solid rgba(216, 216, 216, 1);
    border-bottom: 1px solid rgba(216, 216, 216, 1);
    display: flex;
    .label,
    .content {
      height: 35px;
      font-size: 14px;
    }
    .must-point {
      color: red;
    }
    .label {
      background-color: rgba(245, 247, 251, 1);
      color: #000;
      width: 200px;
      display: flex;
      align-items: center;
      justify-content: end;
      padding-right: 30px;
    }
    .content {
      flex: 1;
      display: flex;
      align-items: center;
      padding-left: 10px;
      border-left: 1px solid rgba(216, 216, 216, 1);
    }
  }
}
</style>
<template>
  <div class="grid-col base-col">
    <div class="label">
      <span class="must-point" v-if="isMust">*</span>{{ label }}
    </div>
    <div class="content" v-if="value !== ''">{{ value }}</div>
    <div class="content" v-else>
      <slot name="desc" />
    </div>
  </div>
</template>

<script setup>
const props = defineProps({
  // 是否带*
  isMust: {
    type: Boolean,
    default: false
  },
  label: {
    type: String,
    default: ''
  },
  value: {
    type: [String, Number],
    default: ''
  }
})
</script>
上次更新: