自己封装一个VUE表格组件

news/2024/7/10 2:40:29 标签: vue

直接上源码

<template>
  <table class="my_table" :style="tableStyle">
    <thead ref="header">
      <tr :style="theadStyle">
        <th v-for="(item, index) in new_columns" :key="item.unique || index"
             :style="{minWidth: typeof item.minWidth === 'number'?item.minWidth + 'px':item.minWidth,
             width: item.width + 'px',
             textAlign: item.headAlign || 'center'}"
             :title="item.title">
             <slot :name="item.slotHeader" :data="{...item,index}">
              {{item.title}}
             </slot>
        </th>
      </tr>
    </thead>
    <tbody :style="tbodyStyle" ref="tableTbody">
            <tr v-for="(item,index) in index_data" :key="(dataKey && item[dataKey]) || index" :style="newRowStyle(item,index)">
                <td v-for="(_item, _index) in new_columns" :key="_item.unique || _index"
                     :style="{minWidth: typeof _item.minWidth === 'number'?_item.minWidth + 'px':_item.minWidth,
                     width: _item.width + 'px',
                     textAlign: _item.textAlign || 'center'}">
                      <slot :name="_item.slot" :data="{...item}">
                        {{chooseKey(item,_item.key)}}
                      </slot>
                </td>
            </tr>
    </tbody>
  </table>
</template>

<script>
export default {
  name: 'MyList',
  props: {
    /* TODO columns接受值: 对象数组
        title: 表头名称
        slotHeader: 表头插槽名称
        slot: 表体插槽
        unique: 默认索引值,必须唯一,便于vue优化
        key: 对应prop:{data}中数据的键值
        minWidth: 对应列最小宽度
    */
    columns: {
      type: Array,
      default: () => []
    },
    data: {
      type: Array,
      default: () => []
    },
    count: {//序号记数初值
      type: Number || String,
      default: 1
    },
    dataKey: {
      type: String,
      default: null
    },
    tbodyStyle: {//自定义tbody的style
      type: String,
      default: null
    },
    tableStyle: {
      type: String,
      default: null
    },
    theadStyle: {
      type: String,
      default: null
    },
    rowStyle: {//自定义tbody中tr的style
      default: null
    }
  },
  computed: {
    new_columns () {//默认值并入columns
      let newArr = []
      for (let i = 0; i < this.columns.length; i++) {
        newArr[i] = JSON.parse(JSON.stringify(this.columns[i]))
        for (let j = 0; j < this.columns_list.length; j++) {
          if (this.columns[i].title === this.columns_list[j].title) {
            newArr[i] = (Object.assign(JSON.parse(JSON.stringify(this.columns_list[j])), this.columns[i]))
            break
          }
        }
      }
      return newArr
    },
    index_data () {//序号处理
      let newArr = this.data
      newArr.map((item, index) => {
        item.C_INDEX = index + (this.count * 1)
      })
      return newArr
    }
  },
  watch: {
  },
  data: () => ({
    columns_list: [//默认值
      {
        title: '序号',
        width: '60',
        key: 'C_INDEX'
      },
      {
        title: '版面',
        key: 'CHNLDESC',
        width: '80'
      },
      {
        title: '标题',
        key: 'TITLE',
        textAlign: 'left'
      },
      {
        title: '类型',
        key: 'DOCTYPE',
        width: '60'
      },
      {
        title: '稿件ID',
        key: 'METADATAID',
        width: '70'
      },
      {
        title: '栏目',
        key: 'CHNLDESC',
        width: '120'
      },
      {
        title: '操作人',
        key: 'TRUENAME',
        width: '86'
      },
      {
        title: '状态',
        key: 'STATUSNAME',
        width: '72'
      },
      {
        title: '最后版本时间',
        key: 'OPERTIME',
        width: '154'
      },
      {
        title: '点击量',
        key: 'HITS',
        width: '70'
      },
      {
        title: '流程版本时间',
        key: 'OPERTIME',
        width: '154'
      },
      {
        title: '焦点图标题',
        key: 'FOCUSIMGTITLE'
      },
      {
        title: '焦点图描述',
        key: 'FOCUSIMAGEDESC'
      },
      {
        title: '稿件标题',
        key: 'TITLE',
        textAlign: 'left'
      },
      {
        title: '渠道',
        width: '120'
      },
      {
        title: '字数',
        key: 'DOCWORDSCOUNT',
        width: '70'
      },
      {
        title: '创建人',
        key: 'TRUENAME',
        width: '90'
      },
      {
        title: '传稿人',
        key: 'OPERNAME',
        width: '90'
      },
      {
        title: '产品',
        key: ['SITEDESC', 'ACCOUNTNAME'],
        width: '90'
      },
      {
        title: '指派人',
        key: 'TRUENAME',
        width: '90'
      },
      {
        title: '所有者',
        key: 'OWNERTRUENAME',
        width: '86'
      },
      {
        title: '作者',
        key: 'AUTHOR_TRUENAME',
        width: '86'
      },
      {
        title: '修改时间',
        key: 'OPERTIME',
        width: '154'
      }
    ]
  }),
  methods: {
    evil (code) {
      let Fn = Function // 一个变量指向Function,防止有些前端编译工具报错
      return new Fn('return ' + code)()
    },
    newRowStyle (item, index) {//rowStyle处理
      if (typeof (this.rowStyle) === 'string') {
        return this.rowStyle
      } else if (typeof (this.rowStyle) === 'object' && (this.rowStyle.field && this.rowStyle.symbol && this.rowStyle.condition)) {
        if (this.evil("'" + this.chooseKey(item, this.rowStyle.field) + "'" + this.rowStyle.symbol + "'" + this.rowStyle.condition + "'")) {
          return this.rowStyle.style
        }
      }
    },
    chooseKey (item, keyArr) {//数组key处理
      if (Object.prototype.toString.call(keyArr) === '[object Array]') {
        for (let i = 0; i < keyArr.length; i++) {
          if (!(item[keyArr[i]] === '' || item[keyArr[i]] === undefined || item[keyArr[i]] === null)) {
            return item[keyArr[i]]
          }
        }
      } else if (Object.prototype.toString.call(keyArr) === '[object String]') {
        return item[keyArr]
      }
    }
  }
}
</script>
<style lang="less">
* {
    -webkit-box-sizing: border-box;
    -moz-box-sizing: border-box;
    box-sizing: border-box;
}
    .my_table{
      width: 100%;
      height: 100%;
    }
    .my_table thead tr{
      border-top: 1px solid #eff1f4;
      color: #2a2a2a;
    }
    .my_table thead tr th{
      font-size: 16px;
      font-weight: 500;
      padding: 14px 0;
      padding-left: 5px;
      padding-right: 5px;
    }
    .my_table tbody{
      overflow-y: 'auto'
    }
    .my_table tbody tr:nth-child(odd) {
      background: #f4f6f7;
    }
    .my_table tbody tr {
      border-top: 1px solid #fff;
      border-bottom: 1px solid #fff;
      color: #3d3d3d;
      &:hover{
        background-color: #f4e0e1!important;
      }
    }
    .my_table  tbody tr td {
      padding-left: 3px;
      padding-right: 1px;
      padding-top: 7px;
      padding-bottom: 7px;
      font-size: 14px;
      text-align: center;
      word-break: break-all;
      height: 45px;
      min-height: 45px;
      max-height: 50px;
    }
</style>

参数表:
在这里插入图片描述
使用示例:

<template>
  <div class="ceshi">
    <CList :columns='columns' :data='data' tableStyle='' theadStyle='' tbodyStyle='' :rowStyle='rowStyle'>
      <template v-slot:TITLE='item'>
        <a class="title" href="../../">{{item.data.TITLE}}</a>
        <span class="mark" v-if="item.data.ORIGINAL==='1'" title="原创稿"></span>
      </template>
      <template v-slot:WEBSTATUSNAME='item'>
        <span v-if="item.data.WEBSTATUSNAME==='待编'" style="color: #ffbe5c;">{{item.data.WEBSTATUSNAME}}</span>
        <span v-else-if="item.data.WEBSTATUSNAME==='撤稿'" style="color: #d64541;">{{item.data.WEBSTATUSNAME}}</span>
      </template>
      <template v-slot:OPERTIME='item'>
        <a class="title" href="../../">{{item.data.OPERTIME}}</a>
      </template>
    </CList>
  </div>
</template>

<script>
import CList from '@/components/MyList'
export default {
  name: 'List',
  data: () => ({
    columns: [],
    data: [],
    rowStyle: {
      field: `WEBSTATUSNAME`,
      symbol: `===`,
      condition: `待修订`,
      style: 'color:#ccc'
    }
  }),
  components: {
    CList
  },
  mounted () {
    this.getData_dzbcs()
  },
  methods: {
    getData_dzbcs () {
      this.$axios.get('../../static/wangzhan.json').then(response => {
        this.columns = [
          {
            title: '序号'
          },
          {
            title: '稿件ID'
          },
          {
            title: '标题',
            slot: 'TITLE'
          },
          {
            title: '类型'
          },
          {
            title: '栏目'
          },
          {
            title: '操作人'
          },
          {
            title: '作者'
          },
          {
            title: '状态',
            slot: 'WEBSTATUSNAME',
            key: 'WEBSTATUSNAME'
          },
          {
            title: '最后版本时间',
            slot: 'OPERTIME'
          }
        ]
        this.data = response.data.DATA
      }, response => {
        console.log('error')
      })
    }
  }
}
</script>

<style lang="less" scoped>
.ceshi{
  width: 1713px;
}
a.title{
    vertical-align: middle;
    display: inline;
    overflow: hidden;
    line-height: 21px;
    display: initial;
    color: #3d3d3d;
    text-decoration: none;
    cursor: pointer;
    &:hover{
      color: #d64541;
    }
}
.mark{
    color: #c2c5cd;
    border-color: #c2c5cd;
    font-size: 11px;
    cursor: pointer;
    margin-left: 7px;
    display: inline-block;
    width: 16px;
    height: 16px;
    border: 1px solid;
    text-align: center;
    line-height: 16px;
    border-radius: 2px;
}
</style>

效果:
在这里插入图片描述

在这里插入图片描述


http://www.niftyadmin.cn/n/1355270.html

相关文章

microsoftbarcode控件9.0安装后不显示_AnyCAD Rapid .Net三维控件WinForms集成教程

1 准备工作AnyCAD Rapid .Net三维控件底层基于C&#xff0c;在Windows下依赖Vistual C 运行时库。因此64位版本需要在客户机上安装vc_redist.x64.exe&#xff0c;32位版本需要安装vc_redist.x86.exe。下载&#xff1a;链接:https://pan.baidu.com/s/145y9R11URPu_JennJStz6A 提…

JS处理除法结果

取余数&#xff1a; a%b取整数&#xff1a; parseInt(a/b)向上取整&#xff1a; Math.ceil(a/b)向下取整&#xff1a; Math.floor(a/b)四舍五入&#xff1a; Math.round(a/b)

python提取矩阵元素_numpy或list数组中最大元素的索引如何使用python获取

numpy或list数组中最大元素的索引如何使用python获取 发布时间&#xff1a;2020-11-17 14:07:49 来源&#xff1a;亿速云 阅读&#xff1a;65 numpy或list数组中最大元素的索引如何使用python获取&#xff1f;针对这个问题&#xff0c;这篇文章详细介绍了相对应的分析和解答&am…

JS 获取DOM的方法汇总

JS 获取DOM的方法汇总 功能方法返回获取bodydocument.bodyDOM对象获取htmldocument.documentElementDOM对象通过标签名获取document.getElementsByTagName数组通过类名获取document.getElementsByClassName数组通过name获取document.getElementsByName数组通过id获取document.…

python怎样装pandas_windows下如何安装Python、pandas

windows下如何安装Python、pandas 本篇主要涵盖以下三部分内容&#xff1a; Python、Pycharm的安装 使用Pycharm创建、运行Python程序 安装pandas 1.Python、Pycharm的安装 Pycharm是一个ide&#xff0c;说简单点就是一个用来编写Python程序的软件&#xff0c;也是个神器&#…

delphi query 存储为dbf_Android Q 存储新特性适配脑壳疼?指南来了!

码个蛋(codeegg)第 692 次推文原文&#xff1a;https://mp.weixin.qq.com/s/aiDMyAfAZvaYIHuIMLAlcg简单回顾下&#xff1a;Android Q 适配 之 存储新特性接下来看看存储新特性的适配啦~ 继续第二章&#xff0c;且看第二回~2. 存储空间限制2.3 适配指导Android Q Scoped Storag…

VUE中的img src问题

VUE中的img src问题 问题表现 当图片文件在/static路径下时&#xff0c;可以正常填入路径即可。当图片文件在/assets路径下是&#xff0c;正常填入字符串路径&#xff0c;将会报错无法找到该图片 问题分析 /assets下的图片被webpack打包&#xff0c;最终路径并不在/assets下。…

vue/element表格拖动排序的实现——sortablejs

目的 实现页面上的表格&#xff0c;能够拖动排序 实现 npm install sortablejs --save引入sortablejs import Sortable from sortablejs;保存sortablejs示例 data() {return {sortable: {}} }, mounted() {this.rowDrop(); } methods: {rowDrop() {const tbody document.q…