关于vue.js:移动端类table组件封装

84次阅读

共计 3206 个字符,预计需要花费 9 分钟才能阅读完成。

简介

一个不怎么高度自定义的挪动端 table 组件,可创立不定数量的列的 table(本人 写着玩 为了当前保护批改款式不便封装起来的

实现思路

  • 表格头部一个循环:循环渲染每一列的列名
  • 表格内容两重循环:外层循环渲染行,内层循环渲染每一行的每一列的内容

实现

环境:vue + vantui,用 van-row + van-col 模仿行和列

// 封装的 table 组件
<template>
  <div class="fake-table">
    <van-row class="fake-table__head">
      <van-col class="col" v-for="(item, index) in headData" :key="index" :span="item.span">{{item.name}}</van-col>
    </van-row>
    <van-row class="fake-table__body" v-for="(item, index) in bodyData" :key="index">
      <template v-for="(colItem, colIndex) in headData">
        <van-col class="col" :span="colItem.span" :key="colIndex" v-if="colItem.prop">
          <-- 这里其实重点只有关注 v -model 绑定的属性名。其余属性看我的项目具体须要,比如说 placeholder 也能够绑定:placeholder="item.placeholder" 等等,只有传进来的数组合乎数据结构就行 -->
          <van-field v-model="item[colItem.prop]" placeholder="请输出名称" :disabled="item.editDisable" :class="[item.editDisable ?'input-diabled':'input-abled']"/>
        </van-col>
        <-- 这里是我的项目须要,不让事件冒泡,如果不须要能够去掉.stop 修饰符。而 capture 就是用来捕捉 slot 进来的元素的事件的,因为在父组件定义事件的话无奈取到这里循环的 colIndex -->
        <van-col class="col" :span="colItem.span" :key="colIndex" @click.stop.capture="doThis($event, index)" v-else>
          <slot></slot>
        </van-col>
      </template>
    </van-row>
  </div>
</template>
<script>
export default {
  props: {
    headData: {
      type: Array,
      default: () => []
    },
    bodyData: {
      type: Array,
      default: () => []
    }
  },
  methods: {doThis(e, rowIdx) {if(e.target.id === 'edit') {this.$emit('edit', rowIdx)
      }
      else if(e.target.id === 'delete') {this.$emit('delete', rowIdx)
      }
    }
  }
}
</script>
<style lang="less" scoped>
@inputPaddingLeft: 5px;
@colPaddingLeft: 10px;

.fake-table /deep/ .van-field__control {padding-left: @inputPaddingLeft;}

.col /deep/ .van-cell {padding: 0;}

.col /deep/ .input-diabled {border: none;}

.col /deep/ .input-abled {border: 1px solid #DDDDDD;}

.table-col {
  height: 100%;
  display: flex;
  justify-content: flex-start;
  align-items: flex-start;
  font-family: PingFangSC-Medium, PingFang SC;
  color: #313131;
}

.fake-table {
  margin: 0 12px;
  &__head, &__body {
    border: 1px solid #DDDDDD;
    &:not(:last-child) {border-bottom: none;}
  }
  &__head {
    height: 40px;
    background: #F5FAFF;
    .col:extend(.table-col) {
      font-size: 14px;
      font-weight: 500;
      line-height: 20px;
      padding: @colPaddingLeft;
    }
  }
  &__body {.col:extend(.table-col) {
      font-size: 13px;
      font-weight: 400;
      line-height: 18px;
      padding: @colPaddingLeft @colPaddingLeft @colPaddingLeft calc(@colPaddingLeft - @inputPaddingLeft);
      &:last-child {padding-left: @inputPaddingLeft;}
    }
  }
}
</style>

应用

// 父组件
// html
<fake-table :headData="tableHead" :bodyData="matirialUsed" @edit="editMatirial" @delete="deleteMatirial">
  <template> 
    <van-icon id="edit" class="edit-btn" name="edit" size="14" color="#268AED" />
    <van-icon id="delete" class="delete-btn" name="delete" size="14" color="#268AED" />
  </template> 
</fake-table>

// script
import fakeTable from '../../components/fake-table'
// ... 省略一些代码
data {
    return {
        tableHead: [{
          name: '资料名称', // 留神传进去的列名
          span: '8',
          prop: 'name' // 留神传进去的列属性名,要跟理论获得的数据的属性名统一,如 matirialUsed 数组的每一项的属性名
        },
        {
          name: '型号',
          span: '6',
          prop: 'model'
        },
        {
          name: '数量',
          span: '5',
          prop: 'num'
        },
        {
          name: '操作',
          span: '5',
          prop: ''
        }],
        matirialUsed: [{ 
          name: '',
          model: '',
          num: '0',
          editDisable: true,  // 是否可编辑
        },
        {
          name: '',
          model: '',
          num: '0',
          editDisable: true,  
        },
        {
          name: '',
          model: '',
          num: '0',
          editDisable: true, 
        },
        {
          name: '',
          model: '',
          num: '0',
          editDisable: true,  
        }]
     }
},
  components: {fakeTable},
  methods: {editMatirial(idx) {let flag = this.matirialUsed[idx]['editDisable']
      this.$set(this.matirialUsed[idx], 'editDisable', !flag)
    },
    deleteMatirial(idx) {
      let temp = this.matirialUsed
      temp.splice(idx, 1)
      this.matirialUsed = temp
    },  
}

正文完
 0