zoukankan      html  css  js  c++  java
  • vue+element对常用表格的简单封装

    在后台管理和中台项目中, table是使用率是特别的高的, 虽然element已经有table组件, 但是分页和其他各项操作还是要写一堆的代码, 所以就在原有的基础上做了进一步的封装

    所涵盖的功能有: 内容展示 , 操作栏 , 选择框 , 分页 , 图片渲染 , 开关 , 过滤器(时间格式化)

    直接上代码

    组件:

    <template>
      <div class="hello">
        <el-table
          :data="tableData"
          style=" 98%"
          @selection-change="handleSelectionChange"
          border>
          <el-table-column v-if="type=='checkbox'" label="选择">
            <template slot-scope="{ row }">
              <el-checkbox v-model="row.isChecked" @change="handleChecked(row)"></el-checkbox>
            </template>
          </el-table-column>
          <el-table-column v-if="type=='selection'" :reserve-selection="true" type="selection" width="55" />
          <el-table-column v-if="type=='index'" type="index" label="序号" width="55" />
          <template v-for="(item, index) of tableTitle">
            <el-table-column
              :prop="item.prop"
              :label="item.label"
              :key="index"
              :min-width="item.width"
            >
              <template slot-scope="{ row, $index }" style="height: 100%;">
                <span v-if="item.filter == 'date'">
                  {{ row[item.prop] | dateFilter }}
                </span>
                <span v-else-if="item.filter == 'time'">
                  {{ row[item.prop] | timeFilter }}
                </span>
                <span v-else-if="item.filter == 'image' && row[item.prop]">
                  <img :src="row[item.prop]" alt="" style="height: 45px;">
                </span>
                <span v-else-if="item.filter == 'switch'">
                  <el-switch
                    v-model="row[item.prop]"
                    @change="change(row, $index)"
                  />
                </span>
                <span v-else>
                  {{ row[item.prop] }}
                </span>
              </template>
            </el-table-column>
          </template>
    <!--      插槽: 操作-->
          <el-table-column label="操作" v-if="ishandle" :width="handleWidth">
            <template slot-scope="scope">
              <slot name="handle" :row="scope.row" :index="scope.$index"></slot>
            </template>
          </el-table-column>
        </el-table>
    
        <el-pagination
          background
          layout="total, sizes, prev, pager, next, jumper"
          :total="total"
          :page-size="pageSize"
          :current-page.sync="current"
          :page-sizes="[10, 20, 30, 40, 50, 100]"
          @size-change="handleSizeChange"
          @current-change="handleCurrentChange"
          >
        </el-pagination>
    
      </div>
    </template>
    
    <script>
    export default {
      name: 'HelloWorld',
      props: {
        handleWidth: { // 操作宽度
          default: 200
        },
        ishandle: { // 是否有操作按钮
          type: Boolean,
          default: true
        },
        type: String, // 单选/多选/或值展示
        tableTitle: Array, // 表头
        tableData: Array, // 数据
      },
      data () {
        return {
          total: 1000,
          pageSize: 10,
          current: 1
        }
      },
      methods: {
        handleSizeChange (size) { // 改变每页数量
          this.pageSize = size
          this.$emit('handleChange', this.pageSize, this.current)
    
        },
        handleChecked (row) { // 单选
          if (row.isChecked) {
            this.tableData.map(item => {
              if (item.id != row.id) {
                this.$set(item, 'isChecked', false)
              }
            })
            this.$emit('handleChecked', row)
          } else {
            this.$emit('handleChecked', '', row)
          }
        },
        handleSelectionChange (row) { // 多选
          this.$emit('handleChecked', row)
        },
        handleCurrentChange (current) { //换页
          this.current = current
          this.$emit('handleChange', this.pageSize, this.current)
        },
        change (row, index) { // 切换开关
          this.$emit('handleSwitch', row, index)
        },
      }
    }
    </script>
    
    <style scoped lang="scss">
    </style>
    

    在父组件中调用:

    <template>
      <div class="home">
        <ComTable
          :handleWidth="200"
          :tableTitle="tableTitle"
          :tableData="tableData"
          @handleChange="handleChange"
          @handleSwitch="handleSwitch"
          @handleChecked="handleChecked"
        >
          <template slot="handle" slot-scope="scope">
            <el-button type="text" size="small">编辑{{scope.index}}</el-button>
          </template>
        </ComTable>
      </div>
    </template>
    
    <script>
    import ComTable from '@/components/Com_Table.vue'
    
    export default {
      name: 'Home',
      components: {
        ComTable
      },
      data () {
        return {
          tableTitle: [{
            prop: 'name',
            label: '姓名',
             '200',
          },{
            prop: 'sex',
            label: '性别',
             '200',
            filter: 'switch',
          },{
            prop: 'url',
            label: '头像',
             '200',
            filter: 'image',
          },{
            prop: 'date',
            label: '出生日期',
             '200',
            filter: 'date'
          },],
          tableData: [{
            id: 1,
            name: '张三',
            sex: true,
            url: 'https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=3202059567,1723387850&fm=26&gp=0.jpg',
            date: new Date()
          },{
            id: 2,
            name: '张三',
            sex: true,
            url: 'https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=3202059567,1723387850&fm=26&gp=0.jpg',
            date: new Date()
          },{
            id: 3,
            name: '张三',
            sex: true,
            url: 'https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=3202059567,1723387850&fm=26&gp=0.jpg',
            date: new Date()
          },{
            id: 4,
            name: '张三',
            sex: true,
            url: 'https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=3202059567,1723387850&fm=26&gp=0.jpg',
            date: new Date()
          },],
        }
      },
      mounted() {
      },
      methods: {
        handleChange (size, current) {
          // 分页改变时的回调----   size: 每页的数量   current: 第几页
          console.log(size, current, 'tableData')
        },
        handleSwitch (row, index) {
          // 切换开关时的回调-========   this.tableData: 滑块值改变后的数据.row: 当前行数据 index: 当前行的索引
          console.log(this.tableData, '--tableData---', row, index)
        },
        handleChecked (val) {
          // 勾选时的回调----   val: 选中的数据  多选是val是数组, 单选时是对象
          console.log(val, 'val===')
    
        }
      }
    }
    </script>
    

    组件中有使用过滤器, 可以定义一下全家的过滤器,然后引入, 这里要根据自己的文件来进行调整. 送上我这里用的两个过滤器

    // 注册全局的过滤器  {{ msg | dateFilter }}
    import Vue from 'vue'
    import moment from 'moment'
    
    // 展示日期格式: YYYY-MM-DD
    Vue.filter('dateFilter', function (dataStr, pattern = 'YYYY-MM-DD') {
      if (dataStr) {
        return moment(dataStr).format(pattern)
      } else {
        return dataStr
      }
    })
    
    // 展示日期格式: YYYY-MM-DD HH:mm:ss
    Vue.filter('timeFilter', function (dataStr, pattern = 'YYYY-MM-DD HH:mm:ss') {
      if (dataStr) {
        return moment(dataStr).format(pattern)
      } else {
        return dataStr
      }
    })
    

    下面是相关参数的说明:

    type: 表格类型. 非必传. 值: selection(多选) / checkbox(单选) 类型: string /index:序号1.2.3...

    handleWidth: 操作栏宽度    非必传   默认200
    
    tableTitle: 表头.  必传.   类型: 数组   例:
        tableTitle: [{
            prop: 'name',  绑定的字段
            label: '姓名',   表头名称
             '200',   列宽度
            filter: 'date'    过滤器. 需要展示的类型. 非必传.  值:
                date: 日期格式(YYYY-MM-DD)
                time: 时间格式(YYYY-MM-DD : HH:mm:ss)
                image: 图片
        }]
    
    > tableData: 要展示的数据. 必传   类型: array   例:
    

    插槽:

      slot="handle":    handle: 插槽名称
      slot-scope="scope":    scope: 组件传递给插槽的值  scope.row:  当前行的内容  scope.index: 当前行的索引
    

    事件:

    handleChange (size, current) {}, //分页改变时的回调----   size: 每页的数量   current: 第几页
    handleSwitch (row, index) {}, // 切换开关时的回调-========   this.tableData: 滑块值改变后的数据.row: 当前行数据 index: 当前行的索引
    handleChecked (val) {},  // 勾选时的回调----   val: 选中的数据  多选是val是数组, 单选时是对象
    

    封装并不是很全面很精致, 但是至少可以省点事~~~

    以上代码还未经过项目的检验, 属于雏形, 还需要不断的优化和改进, 如遇坑, 请留言. 谢谢!!!

  • 相关阅读:
    硬盘
    [编译] 6、开源两个简单且有用的安卓APP命令行开发工具和nRF51822命令行开发工具
    [编译] 5、在Linux下搭建安卓APP的开发烧写环境(makefile版)—— 在Linux上用命令行+VIM开发安卓APP
    [Zephyr] 1、在linux上安装Zephyr-OS并跑DEMO
    [编译] 4、在Linux下搭建nRF51822的开发烧写环境(makefile版)
    [BlueZ] 2、使用bluetoothctl搜索、连接、配对、读写、使能notify蓝牙低功耗设备
    [BlueZ] 1、Download install and use the BlueZ and hcitool on PI 3B+
    [python] 3 、基于串口通信的嵌入式设备上位机自动测试程序框架(简陋框架)
    [ARCH] 1、virtualbox中安装archlinux+i3桌面,并做简单美化
    [编译] 3、在Linux下搭建51单片机的开发烧写环境(makefile版)
  • 原文地址:https://www.cnblogs.com/hubufen/p/14202517.html
Copyright © 2011-2022 走看看