封装一个可编辑的表单,用于统计月度计划

封装一个可编辑的表单,用于统计月度计划

在正式开始封装之前我们要简单理解一下什么叫做公共组件,根据名字可以得知,这东西相当于合作社的老黄牛,谁家需要用打声招呼拿过去用,所以在封装公共组件的时候我们需要注意的是三个问题:

  1. 谁去用:将公共组件引入到哪个组件中
  2. 能不能用:拿来的公共组件是否可以搭配我的组件完成逻辑
  3. 用来干什么:完成相应的项目需求

等搞清楚了这三个问题我们就大致了解到了有一个公共组件必须具备的条件

  • 公共组件必须是所有组件都可以使用的,因此我们需要创建一个components文件夹用于存放公共组件。
  • 公共组件必须满足拿来即用,因此需要对于父组件传过来的情况作不同的考量,根据不同的数据书写不同的逻辑。

接下来就给大家写一个基于css、html完成的表格。

  1. 首先创建一个components文件夹
  2. 创建EditTable.vue文件
    template部分
      <template>
         <div class="table_box">
           <div class="monthName">
             <span class="unit_text">单位:万吨</span>
             {{ props.title }}
           </div>
           <div class="table_header">
             <div class="header_box" v-for="item in tableData.columns" :key="item.dataIndex">
               {{ item.monthName }}
             </div>
           </div>
           <div class="table_body">
             <div class="body_box" :style="{ pointerEvents: lastYear ? 'none' : 'all' }" v-for="item in tableData.data" :key="item.monthName">
               <input type="text" v-if="item.editable" v-model="item.monthValue" @blur="save(item)" />
               <span v-else @click="edit(item)">{{ item.monthValue }}</span>
             </div>
           </div>
         </div>
       </template>

script部分

   <script setup>
         import { reactive, watch, ref } from 'vue';
         const props = defineProps({
           title: { type: String, default: '' },
         });
        // 接受父级组件传过来的值   
         const emit = defineEmits(['getTableData']);
       
         const tableData = reactive({
             //因为后端要求所以将表头与表数据分开了,可以自行修改
           data: [
             {
               monthName: 'total',
               monthValue: '0',
               editable: false,
             },
             {
               monthName: '01',
               monthValue: '0',
               editable: false,
             },
             {
               monthName: '02',
               monthValue: '0',
               editable: false,
             },
             {
               monthName: '03',
               monthValue: '0',
               editable: false,
             },
             {
               monthName: '04',
               monthValue: '0',
               editable: false,
             },
             {
               monthName: '05',
               monthValue: '0',
               editable: false,
             },
             {
               monthName: '06',
               monthValue: '0',
               editable: false,
             },
             {
               monthName: '07',
               monthValue: '0',
               editable: false,
             },
             {
               monthName: '08',
               monthValue: '0',
               editable: false,
             },
             {
               monthName: '09',
               monthValue: '0',
               editable: false,
             },
             {
               monthName: '10',
               monthValue: '0',
               editable: false,
             },
             {
               monthName: '11',
               monthValue: '0',
               editable: false,
             },
             {
               monthName: '12',
               monthValue: '0',
               editable: false,
             },
           ],
           columns: [
             { monthName: '总计', dataIndex: 'total', editable: false },
             { monthName: '1月', dataIndex: 'january', editable: true },
             { monthName: '2月', dataIndex: 'february', editable: true },
             { monthName: '3月', dataIndex: 'march', editable: true },
             { monthName: '4月', dataIndex: 'april', editable: true },
             { monthName: '5月', dataIndex: 'may', editable: true },
             { monthName: '6月', dataIndex: 'june', editable: true },
             { monthName: '7月', dataIndex: 'july', editable: true },
             { monthName: '8月', dataIndex: 'august', editable: true },
             { monthName: '9月', dataIndex: 'september', editable: true },
             { monthName: '10月', dataIndex: 'october', editable: true },
             { monthName: '11月', dataIndex: 'november', editable: true },
             { monthName: '12月', dataIndex: 'december', editable: true },
           ],
         });
         // 可编辑
         const edit = (row) => {
           row.editable = true;
         };
         // 保存数据
         const save = (row) => {
           row.editable = false;
           const monthArr = tableData.data.map((ele) => {
             if (ele.monthName === 'total') return 0;
             else return Number(ele.monthValue);
           });
           if (row.monthName !== 'total') {
             tableData.data[0].monthValue = monthArr.reduce((per, cur) => per + cur, 0);
           }
         };
       
         // 判断是否是去年计划,是的话不可编辑表格
         const lastYear = ref(false);
         watch(
           () => [props.title, lastYearList],
           (newData) => {
             lastYear.value = newData[0] === '去年月度计划时间及数量' ? true : false;
           },
           {
             immediate: true,
             deep: true,
           }
         );
         // 发送数据
         function sendTableData() {
           emit('getTableData', tableData.data);
         }
         // 改变数据
         function changeTableData(data) {
           if (data) {
             tableData.data = data;
             const monthArr = tableData.data.map((ele) => {
               if (ele.monthName === 'total') return 0;
               else return Number(ele.monthValue);
             });
             // 计算总数     
             tableData.data[0].monthValue = monthArr.reduce((per, cur) => per + cur, 0);
           }
         }
         // 清楚数据,可以自行修改
         function clearTable() {
           tableData.data = [
             {
               monthName: 'total',
               monthValue: '0',
               editable: false,
             },
             {
               monthName: '01',
               monthValue: '0',
               editable: false,
             },
             {
               monthName: '02',
               monthValue: '0',
               editable: false,
             },
             {
               monthName: '03',
               monthValue: '0',
               editable: false,
             },
             {
               monthName: '04',
               monthValue: '0',
               editable: false,
             },
             {
               monthName: '05',
               monthValue: '0',
               editable: false,
             },
             {
               monthName: '06',
               monthValue: '0',
               editable: false,
             },
             {
               monthName: '07',
               monthValue: '0',
               editable: false,
             },
             {
               monthName: '08',
               monthValue: '0',
               editable: false,
             },
             {
               monthName: '09',
               monthValue: '0',
               editable: false,
             },
             {
               monthName: '10',
               monthValue: '0',
               editable: false,
             },
             {
               monthName: '11',
               monthValue: '0',
               editable: false,
             },
             {
               monthName: '12',
               monthValue: '0',
               editable: false,
             },
           ];
         }
         // 因为使用了setup语法糖,所以想要在父级组件中调用方法需要单独暴露,不然拿不到,如果你使用setup函数就不需要这样做
         defineExpose({
           sendTableData,
           changeTableData,
           clearTable,
         });
       </script>

Css部分

      <style lang="less" scoped>
      .table_box {
        display: flex;
        flex-direction: column;
        margin-bottom: 20px;
        .monthName {
          width: 100%;
          height: 25px;
          font-size: 18px;
          font-weight: bold;
          color: #000;
          text-align: center;
          margin: 10px 0;
          .unit_text {
            float: left;
            font-size: 16px;
            font-weight: normal;
          }
        }
        .table_header {
          width: 100%;
          height: 35px;
          display: grid;
          grid-template-columns: repeat(13, 1fr);
          grid-template-rows: repeat(1, 1fr);
          .header_box {
            border: 1px solid #000;
            text-align: center;
            line-height: 35px;
            border-right: none;
          }
          .header_box:nth-last-child(1) {
            border-right: 1px solid #000;
          }
        }
        .table_body {
          width: 100%;
          height: 35px;
          display: grid;
          grid-template-columns: repeat(13, 1fr);
          grid-template-rows: repeat(1, 1fr);
          .body_box {
            border: 1px solid #000;
            text-align: center;
            line-height: 35px;
            border-right: none;
            border-top: none;
            input {
              width: 100%;
              height: 98%;
              text-align: center;
              border-top: none;
              border: 1px solid #000;
              outline: none;
            }
            span {
              display: inline-block;
              width: 100%;
              height: 100%;
            }
          }
          .body_box:nth-last-child(1) {
            border-right: 1px solid #000;
          }
        }
      }
    
      .box {
        background-color: #ddd;
        padding: 20px;
        text-align: center;
      }
    </style>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值