小程序自定义表格组件

时间:2024-03-14 08:28:33
<template>
  <view class="vant-table">
    <view v-if="tableData.length === 0"></view>
    <view v-else>
        <table cellspacing="0" :style="bgcolor" style="width:100%" class="table">
            <tr class="head">
                <th class="th" v-for="(item, index) in option.column" :key="index">{{ item.label }}</th>
            </tr>
            <van-swipe-cell :right-width="60">
              <tr v-for="(item, index) in tableData" :key="index" class="list-tr">
                <td v-for="(context, i) in option.column" :key="i">
                  {{ item[context.tableDataprop] }}
                </td>
              </tr>
              <view slot="right" class="van-swipe-cell__right" @click="deleteItem(index)">删除</view>
            </van-swipe-cell>
            <!-- 根据需要动态显示合计行 -->
            <tr v-if="needTotal" class="total-row">
              <td class="total-td">合计</td>
              <td v-for="(context, i) in option.column" :key="i"> 
                <!-- 判断是否需要合计 --> 
                <template v-if="context.needTotal"> 
                  {{ calculateTotal(context.tableDataprop) }} 
                </template> 
                <template v-else> 
                  <!-- 不需要合计的列显示空白 -->
                </template> 
              </td> 
              <!-- <div v-for="(context, i) in option.column"  :key="i">
                <td>
                  <template v-if="context.needTotal && context.tableDataprop">
                    {{ calculateTotal(context.tableDataprop) }}
                  </template>
                  <template v-else>
                  </template>
                </td>
              </div> -->
            </tr>
        </table>
    </view>
  </view>
</template>
<script>
export default {
  name:'TableVant',
  props:{
    bgcolor:{
      type: Object,
      default: {}
    },
    tableData:{
      type: Array,
      default: []
    },
    option:{
      type: Object,
      default: {}
    },
    onDelete: {
      type: Function,
      required: true
    },
    // 是否需要合计
    needTotal: {
      type: Boolean,
      default: false
    }
  },
  created() {},
  methods: {
    deleteItem(index) {
      // 在这里处理删除操作
      this.onDelete(index); // 触发传入的删除方法
    },
    // 求和
    calculateTotal(dataProp) {
      // 计算指定列数据的合计值
      let total = 0;
      for (let item of this.tableData) {
        total += parseFloat(item[dataProp]);
      }
      return total;
    }
  },
};
</script>

<style  scoped>

.table {
    width: 100%;
}
.head{
    height: 69rpx;
    display: flex;
    justify-content: space-around;
    background-color: #F6F7FA;
}
.th {
  height: 20rpx;
  line-height: 20rpx;
  /* background-color: rgba(246,247,250,1.000000); */
  color: rgba(65,64,64,1);
  font-size: 23rpx;
  font-family: SourceHanSansSC-Regular;
  font-weight: normal;
  text-align: center;
  white-space: nowrap;
  line-height: 34rpx;
  padding: 20rpx 0;
}
.list-tr {
    height: 90rpx;
    display: flex;
    justify-content: space-around;
    background-color: #fff;
    border-bottom: 1rpx solid #E4E4E4;
}
.list-tr:nth-child(2n) {
  /*background-color: #33333b;*/
}
td {
    text-align: center;
    font-family: SourceHanSansSC, SourceHanSansSC;
    font-weight: 400;
    font-size: 23rpx;
    color: #414040;
    line-height: 90rpx;
    font-style: normal;
}
.van-swipe-cell__right{
  display: inline-block;
  width: 65rpx;
  height: 23px;
  margin-top: 20rpx;
  border-radius: 6rpx;
  /* padding: 10rpx; */
  font-size: 23rpx;
  line-height: 23px;
  color: #fff;
  text-align: center;
  background-color: #f44;
}
.total-row{
  background:#F6F7FA ;
  height: 69rpx;
  display: flex;
  justify-content: space-around;
}
.total-td{
  position: absolute;
  left: 30rpx;
}
</style>

外部组件引用

<template>
    <view class="add-box">
      <view class="form-box2">
          <view class="title-box" @click="toggleTable">
          <img src="/static/images/production/add.png" alt="" class="title-img" @click="addInventory">
          <text class="title">股东结构</text>
          <uni-icons class="rt" :type="isExpanded ? 'arrowup' : 'arrowdown'" color="#bcbcbc"></uni-icons>
          </view>
          <view v-if="isExpanded">
            <vant-table :option="option" :tableData="dataForm.beefCattleNums" :onDelete="stockDelHandle" :needTotal="isNeedTotal"></vant-table>
          </view>
      </view>
      <view class="footer-box">
        <button type="default" class="cus-btn" plain="true" @click="submitHandle">保存</button>
      </view>
      <uni-popup ref="inventoryPopup" class="popup-cus">
        <add-structure @addInventoryHandle="addInventoryHandle" @closeInventoryHandle="closeInventoryHandle"></add-structure>
      </uni-popup>
    </view>
  </template>
  
  <script>
  import AddStructure from '../components/add-gdStructure.vue'
  import VantTable from '../../components/table.vue'
  export default {
    components:{
      AddStructure,
      VantTable,
    },
    data() {
      return {
        isExpanded:false,
        isNeedTotal:true,
        option: {
          column: [
              {
              label: '股东名称',
              tableDataprop: 'shareholder_name',
              needTotal:false,
              },
              {
              label: '持股比例(%)',
              tableDataprop: 'shareholding_ratio',
              needTotal:true,
              },
              {
              label: '认缴金额(万元)',
              tableDataprop: 'subscription_capital',
              needTotal:true,
              },
              {
              label: '实缴金额(万元)',
              tableDataprop: 'paid_in_capital',
              needTotal:true,
              },
              {
              label: '出资方式',
              tableDataprop: 'capital_contribution_type',
              needTotal:false,
              }
          ]
        },
        dataForm: {
          operationId: '',
          creationMonth: '',
          industry: '',
          industryName: '',
          productType: '',
          productTypeName: '',
          productStatus: '',
          cowMaxScale: '',
          beefCattleNums: [
          ],
          deposit1:'',
          deposit2:'',
          deposit3:''
        },
        selectedTypeIndex:-1,
        typeList:[{"dictValue":"货币","dictCode":"货币"},{"dictValue":"实物","dictCode":"票据贴现"},{"dictValue":"知识产权","dictCode":"知识产权"}],
      }
    },
    methods: {
      onTypePickerChange(e,params) {
				const index = e.detail.value
				if (index === this.selectedTypeIndex) return
				  this.selectedTypeIndex = index
          console.log(this.typeList[0]);
          console.log(this.typeList[index],'this.typeList[index]');
          this.dataForm.beefCattleNums[params].fatCalfNum2 = this.typeList[index].dictValue;
			},
      addInventory(){
        console.log(1222);
        this.$refs.inventoryPopup.open()
      },
      addInventoryHandle(data){
        this.$refs.inventoryPopup.close()
        this.dataForm.beefCattleNums.push(Object.assign({}, data))
      },
      closeInventoryHandle(){
        this.$refs.inventoryPopup.close()
      },
      // 删除操作
      async stockDelHandle(index) {
        uni.showModal({
          title: '提示',
          content: '确认是否删除当前数据项?',
          confirmText: '确定',
          cancelText: '取消',
          confirmColor: '#35AB3B',
          success: async result => {
            if (result.confirm) {
              // uni.showLoading({
              //   title: '加载中...',
              //   mask: true
              // })
              // const [err, res] = await stockDel({
              //   id
              // })
              // uni.hideLoading()
              // if (err) return
              // if (res.code !== 0) {
              //   return uni.showToast({
              //     title: res.msg || '操作失败!',
              //     icon: 'none'
              //   })
              // }
              // this.getInfo(true)
              this.dataForm.beefCattleNums.splice(index,1)
            } else if (result.cancel) {
                console.log('用户点击取消')
            }
          }
        })
      },
      toggleTable() {
        this.isExpanded = !this.isExpanded;
      },
      // 保存
      submitHandle(){
        console.log('保存成功!')
      },
    }
  }
  </script>
  
  <style lang="scss" scoped>
     @import "../../../../../static/css/add_tcpublic.scss";

  </style>