多表格,多表头

2020-02-12  本文已影响0人  Biao_349d

bem.js

/*
 * @Description: In User Settings Edit
 * @Author: your name
 * @Date: 2019-09-23 17:20:11
 * @LastEditTime : 2020-02-02 19:22:15
 * @LastEditors  : Please set LastEditors
 */
/**
 * bem helper
 * b() // 'button'
 * b('text') // 'button__text'
 * b({ disabled }) // 'button button--disabled'
 * b('text', { disabled }) // 'button__text button__text--disabled'
 * b(['disabled', 'primary']) // 'button button--disabled button--primary'
 */
const ELEMENT = '__'
const MODS = '--'

const join = (name, el, symbol) =>
  el ? (name ? name + symbol + el : el) : name

const prefix = (name, mods) => {
  if (typeof mods === 'string') {
    return join(name, mods, MODS)
  }

  if (Array.isArray(mods)) {
    return mods.map(item => prefix(name, item))
  }

  const ret = {}
  Object.keys(mods).forEach(key => {
    ret[name + MODS + key] = mods[key]
  })
  return ret
}

export default {
  methods: {
    b(el, mods) {
      const { name } = this.$options

      if (el && typeof el !== 'string') {
        mods = el
        el = ''
      }
      el = join(name, el, ELEMENT)

      return mods ? [el, prefix(el, mods)] : el
    }
  }
}

more-table.vue

<!--
 * @Author: your name
 * @Date: 2020-02-02 21:42:27
 * @LastEditTime : 2020-02-08 10:25:59
 * @LastEditors  : Please set LastEditors
 * @Description: In User Settings Edit
 * @FilePath: \whyqh5\src\components\hd.vue
 -->
<template>
  <div :class="b('wrapper', ['wrapper'])">
    <table cellpadding="0" cellspacing="0" border="1">
      <tbody :class="b('wrapper', ['wrapper--th'])">
        <tr
          v-for="(item, index) in theadColumns"
          :key="index"
          :class="b('wrapper', ['wrapper--tr'])" class="clearfix"
          :colspan="getMax((item || []), 'colspan') || 1"
          :rowspan="getMax((item || []), 'rowspan') || 1"
        >
          <td
            v-for="(item2, index2) in item || []"
            :key="index2"
            :class="b('wrapper', ['wrapper--tr--td'])"
            v-bind="{
              ...(item2.bind || {})
            }"
          >
            <div :class="b('wrapper', ['wrapper--tr--td--context'])">
              {{ item2.name }}
            </div>
          </td>
        </tr>
      </tbody>
    </table>
     <table
      v-for="(column, columnIndex) in columns"
      :key="columnIndex"
      cellpadding="0" cellspacing="0" border="1"
    >
       <tbody :class="b('wrapper', ['wrapper--tb'])">
        <tr
          v-for="(item, index) in column"
          :key="index"
          :class="b('wrapper', ['wrapper--tr'])" class="clearfix"
          :colspan="getMax((item || []), 'colspan') || 1"
          :rowspan="getMax((item || []), 'rowspan') || 1"
        >
          <td
            v-for="(item2, index2) in item || []"
            v-show="((data[columnIndex] || [])[index] || {})[item[index2].key]"
            :key="index2"
            :class="b('wrapper', ['wrapper--tr--td'])"
            v-bind="{
              ...(item2.bind || {})
            }"
          >
            <div :class="b('wrapper', ['wrapper--tr--td--context'])">
              {{filterZero((( data[columnIndex] || [])[index] || {})[item[index2].key]) }}
            </div>
          </td>
        </tr>
      </tbody>
     </table>
    </div>
</template>
<script>
  export default {
    name: 'CommonMoreTable',
    props: {
      columns: {
        type: Array,
        default: () => {
          return [
            []  // 这里按照tbodyColumns的数据填
          ]
        }
      },
      theadColumns: {
        type: Array,
        default: () => {
          return []
          // [
          //   [
          //     {
          //       name: '类别',
          //       key: 'name1',
          //       bind: {
          //         rowspan: '2',
          //         width: '20%',
          //       }
          //     },
          //     {
          //       name: '品名',
          //       key: 'name2',
          //       bind: {
          //         rowspan: '2',
          //         width: '20%',
          //       }
          //     },
          //     {
          //       name: '未来需求量',
          //       key: 'name3',
          //       bind: {
          //         colspan: "3",
          //         rowspan: "1",
          //         width: '40%',
          //         dataShow: false
          //       }
          //     },
          //     {
          //       name: '单位',
          //       key: 'name4',
          //       bind: {
          //         rowspan: '2',
          //         width: '20%',
          //       }
          //     }
          //   ],
          //   [
          //     {
          //       name: '未来7天',
          //       key: 'name5',
          //       bind: {
          //         rowspan: '1',
          //       }
          //     },
          //     {
          //       name: '未来15天',
          //       key: 'name6',
          //       bind: {
          //         rowspan: '1',
          //       }
          //     },
          //     {
          //       name: '未来30天',
          //       key: 'name7',
          //       bind: {
          //         rowspan: '1',
          //       }
          //     }
          //   ]
          // ]
        }
      },
      tbodyColumns: {
        type: Array,
        default: () => {
          return []
          // [
          //   [
          //     {
          //       key: 'name1',
          //       bind: {
          //         rowspan: '4',
          //         width: '20%',
          //       }
          //     },
          //     {
          //       key: 'name2',
          //       bind: {
          //         rowspan: '1',
          //         width: '20%',
          //       }
          //     },
          //     {
          //       key: 'name4',
          //       bind: {
          //         colspan: "1",
          //         rowspan: "1",
          //         width: '10%',
          //       }
          //     },
          //     {
          //       key: 'name5',
          //       bind: {
          //         rowspan: '1',
          //         width: '13.4%',
          //       }
          //     },
          //     {
          //       key: 'name6',
          //       bind: {
          //         rowspan: '1',
          //         width: '13.4%',
          //       }
          //     },
          //     {
          //       key: 'name7',
          //       bind: {
          //         rowspan: '1',
          //         width: '20%',
          //       }
          //     }
          //   ],
          //   [
          //     {
          //       key: 'name1',
          //       bind: {
          //         rowspan: '4',
          //         width: '20%',
          //       }
          //     },
          //     {
          //       key: 'name2',
          //       bind: {
          //         rowspan: '1',
          //         width: '20%',
          //       }
          //     },
          //     {
          //       key: 'name4',
          //       bind: {
          //         colspan: "1",
          //         rowspan: "1",
          //         width: '13.33%',
          //       }
          //     },
          //     {
          //       key: 'name5',
          //       bind: {
          //         rowspan: '1',
          //         width: '13.33%',
          //       }
          //     },
          //     {
          //       key: 'name6',
          //       bind: {
          //         rowspan: '1',
          //         width: '13.34%',
          //       }
          //     },
          //     {
          //       key: 'name7',
          //       bind: {
          //         rowspan: '1',
          //         width: '20%',
          //       }
          //     }
          //   ],
          //   [
          //     {
          //       key: 'name1',
          //       bind: {
          //         rowspan: '4',
          //         width: '20%',
          //       }
          //     },
          //     {
          //       key: 'name2',
          //       bind: {
          //         rowspan: '1',
          //         width: '20%',
          //       }
          //     },
          //     {
          //       key: 'name4',
          //       bind: {
          //         colspan: "1",
          //         rowspan: "1",
          //         width: '13.33%',
          //       }
          //     },
          //     {
          //       key: 'name5',
          //       bind: {
          //         rowspan: '1',
          //         width: '13.33%',
          //       }
          //     },
          //     {
          //       key: 'name6',
          //       bind: {
          //         rowspan: '1',
          //         width: '13.34%',
          //       }
          //     },
          //     {
          //       key: 'name7',
          //       bind: {
          //         rowspan: '1',
          //         width: '20%',
          //       }
          //     }
          //   ],
          //   [
          //     {
          //       key: 'name1',
          //       bind: {
          //         rowspan: '4',
          //         width: '20%',
          //       }
          //     },
          //     {
          //       key: 'name2',
          //       bind: {
          //         rowspan: '1',
          //         width: '20%',
          //       }
          //     },
          //     {
          //       key: 'name4',
          //       bind: {
          //         colspan: "1",
          //         rowspan: "1",
          //         width: '13.33%',
          //       }
          //     },
          //     {
          //       key: 'name5',
          //       bind: {
          //         rowspan: '1',
          //         width: '13.33%',
          //       }
          //     },
          //     {
          //       key: 'name6',
          //       bind: {
          //         rowspan: '1',
          //         width: '13.34%',
          //       }
          //     },
          //     {
          //       key: 'name7',
          //       bind: {
          //         rowspan: '1',
          //         width: '20%',
          //       }
          //     }
          //   ],
          // ]
        }
      },
      data: {
        type: Array,
        default: () => {
          return [
            []  // 按照下面的数据放
          ]
          // [
          //   {
          //     name1: '防护',
          //     name2: '外科口罩',
          //     name4: '861',
          //     name5: '1845万',
          //     name6: '3690万',
          //     name7: '万个'
          //   },
          //   {
          //     // name1: '防护',
          //     name2: '医用防护口罩',
          //     name4: '105',
          //     name5: '210',
          //     name6: '420',
          //     name7: '万个'
          //   },
          //   {
          //     // name1: '防护',
          //     name2: '医用防护服',
          //     name4: '530',
          //     name5: '105',
          //     name6: '210',
          //     name7: '万个'
          //   },
          //   {
          //     // name1: '防护',
          //     name2: '医用目镜/医用隔离眼罩',
          //     name4: '7000',
          //     name5: '120000',
          //     name6: '120000',
          //     name7: '套'
          //   }
          // ]
        }
      },
      border: {
        type: Boolean,
        default: false
      },
      tableStyle: {
        type: Object,
        default: () => {
          return {}
        }
      },
    },
    // computed: {
    //   isShowTd(columnIndex, index, index2, item) {
    //     const val = ((this.data[columnIndex] || [])[index] || {})[item[index2].key]
    //     if (typeof val === 'number') {
    //       return '' + val
    //     }
    //     return val
    //   }
    // },
    filters: {
      filterZero(val) {
        if (typeof val === 'number') {
          return '' + val
        }
        return val
      }
    },
    methods: {
      getMax(arr, name) {
        return (arr.reduce(function (pre, curv) {
            return pre[name] < curv[name] ? curv : pre;
        }).bind || {})[name]
      },
      filterZero(val) {
        if (typeof val === 'number') {
          return '' + val
        }
        return val
      }
    }
  }
</script>
<style lang="less">
.CommonMoreTable{
  &__wrapper{
    &--wrapper{
      table, caption, tbody, tfoot, thead, tr, th, td{
        // border: 1px solid #000;
      }
      table{
        display: table;
        width: 100%;
        border-color: #E6E6E6;
        border: none;
        box-sizing: border-box;
        TABLE-LAYOUT: fixed;
        WORD-BREAK: break-all;
        &:not(:first-child){
          border-top: 0;
        }
      }
      tbody{
        border-color: #E6E6E6;
        display: table;
        width: 100%;
        border: none;
        box-sizing: border-box;
        TABLE-LAYOUT: fixed;
        WORD-BREAK: break-all;
      }
      &--th{
        background:rgba(253,248,248,1);
        // overflow: hidden;
        // display: block;
        display: table;
        width: 100%;
        .CommonMoreTable__wrapper--wrapper--tr{
          &--td{
            font-size:12px;
            font-family:PingFangSC-Light,PingFang SC;
            font-weight:300;
            color:rgba(208,2,27,1);
            line-height:20px;
            padding: 8px 0px;
            &--context{
              display: inline;
              word-break:break-all;
              word-wrap:break-word;
              font-size:12px;
              box-sizing: border-box;
              color:rgba(208,2,27,1);
            }
          }
        }
        // &:after{
        //   content: "";
        //   width:374px;
        //   height:1px;
        //   background:rgba(255,236,239,1);
        //   display: block;
        // }
      }
      &--tb{
      }
      &--tr{
        // padding: 3px 0;
        //   display: flex;
        //   justify-content: center; /* 水平居中 */
        //   align-items: center;     /* 垂直居中 */
        border: none;
        box-sizing: border-box;
        &--td{
          padding: 8px 3px;
          text-align: left;
          box-sizing: border-box;
          text-align:center; /** 设置水平方向居中 */
          vertical-align:middle; /** 设置垂直方向居中 */
          border-color: #E6E6E6;
          &:first-child{
            // padding-left: 14px;
          }
          &--context{
            display: inline;
            word-break:break-all;
            word-wrap:break-word;
            font-size:12px;
            box-sizing: border-box;
            color: #666666;
          }
        }
      }
      &--tr&--tr--border{
          //  border-bottom: 1px solid #E1E1E1;
        &:not(:last-child){
          // margin-top: 3px;
          //  border-bottom: 1px solid #E1E1E1;
        }
      }
    }
  }
}
</style>

调用方法

<template>
  <div>
    <CommonMoreTable :theadColumns="theadColumns" :columns="columns2" :data="data2"></CommonMoreTable>
  </div>
</template>
<script>
  import CommonMoreTable from '@/components/more-table/_base';
import { mapState, mapActions } from 'vuex';
  const keyObj = {
    key1: 'category',
    key2: 'productName',
    key3: 'name3',
    key4: 'next7Days',
    key5: 'next15Days',
    key6: 'next30Days',
    key7: 'unit',
  }
  const columnsObj = {
    key1: {
      key: keyObj.key1,
      bind: {
        rowspan: '4',
        width: '15%',
      }
    },
    key2: {
      key: keyObj.key2,
      bind: {
        rowspan: '1',
        width: '20%',
      }
    },
    key4: {
      key: keyObj.key4,
      bind: {
        colspan: "1",
        rowspan: "1",
        width: '18.3%',
      }
    },
    key5: {
      key: keyObj.key5,
      bind: {
        rowspan: '1',
        width: '18.3%',
      }
    },
    key6: {
      key: keyObj.key6,
      bind: {
        rowspan: '1',
        width: '18.3%',
      }
    },
    key7:{
      key: keyObj.key7,
      bind: {
        rowspan: '1',
        width: '10%',
      }
    }
  }
  export default {
    components: {
      CommonMoreTable
    },
    data() {
      return {
        theadColumns: [
            [
              {
                name: '类别',
                key: keyObj.key1,
                bind: {
                  rowspan: '2',
                  width: '15%',
                }
              },
              {
                name: '品名',
                key: keyObj.key2,
                bind: {
                  rowspan: '2',
                  width: '20%',
                }
              },
              {
                name: '未来需求量',
                key: keyObj.key3,
                bind: {
                  colspan: "3",
                  rowspan: "1",
                  width: '55%',
                }
              },
              {
                name: '单位',
                key: keyObj.key7,
                bind: {
                  rowspan: '2',
                  width: '10%',
                }
              }
            ],
            [
              {
                name: '未来7天',
                key: keyObj.key4,
                bind: {
                  rowspan: '1',
                  width: '18.3%',
                }
              },
              {
                name: '未来15天',
                key: keyObj.key5,
                bind: {
                  rowspan: '1',
                  width: '18.3%',
                }
              },
              {
                name: '未来30天',
                key: keyObj.key6,
                bind: {
                  rowspan: '1',
                  width: '18.3%',
                }
              }
            ]
          ],
    protectKeyMaterials: [
            {
                "category":"分类一",
                "next15Days":"111",
                "next30Days":"222",
                "next7Days":"333",
                "productName":"A",
                "unit":"万个"
            },
            {
                "category":"分类一",
                "next15Days":"210",
                "next30Days":"420",
                "next7Days":"105",
                "productName":"B",
                "unit":"万个"
            },
            {
                "category":"分类一",
                "next15Days":"105",
                "next30Days":"210",
                "next7Days":"53",
                "productName":"c",
                "unit":"万套"
            },
            {
                "category":"分类一",
                "next15Days":"120000",
                "next30Days":"120000",
                "next7Days":"70000",
                "productName":"d",
                "unit":"副"
            },
            {
                "category":"分类2",
                "next15Days":"22500",
                "next30Days":"45000",
                "next7Days":"10500",
                "productName":"A",
                "unit":"箱"
            },
            {
                "category":"分类2",
                "next15Days":"225000",
                "next30Days":"450000",
                "next7Days":"105000",
                "productName":"B",
                "unit":"瓶"
            },
            {
                "category":"分类2",
                "next15Days":"225000",
                "next30Days":"450000",
                "next7Days":"105000",
                "productName":"C",
                "unit":"台"
            },
            {
                "category":"分类3",
                "next15Days":"600",
                "next30Days":"600",
                "next7Days":"600",
                "productName":"A",
                "unit":"台"
            },
        ]

      }
    },
    computed: {
      columns2() {
        return this.data2.map(item => {
          return (item || []).map((item2, index) => {
            const arr = []
            if (index  == 0) {
              arr.push(
                {
                  ...columnsObj.key1,
                  bind: {
                    ...columnsObj.key1.bind,
                    rowspan: item.length
                  }
                }
              )
            }
            return [
              ...arr,
              ...[
                columnsObj.key2,
                columnsObj.key4,
                columnsObj.key5,
                columnsObj.key6,
                columnsObj.key7,
              ]
            ]
          })
        })
      },
      data2() {
        const obj = {}
        this.protectKeyMaterials.forEach(item => {
          // category
          if (Object.keys(obj).indexOf(item[keyObj.key1]) === -1) {
            obj[item[keyObj.key1]] = []
            obj[item[keyObj.key1]].push(item)
          } else {
            obj[item[keyObj.key1]].push(item)
          }
        })
        return Object.values(obj)
      }
    },
    created() {
      this.getProtectKeyMaterials()
    },
    mounted() {
    },
    methods: {
      ...mapActions(['getProtectKeyMaterials'])
    }
  }
</script>

image.png
上一篇 下一篇

猜你喜欢

热点阅读