一个vue工程下表单+分页表格的组件

本文介绍如何在Vue项目中实现数据表格的级联监听、空数据处理、加载指示、高效传参、日期格式转换,以及表单验证的最佳实践,包括日期范围选择器和分页组件的定制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在开始之前请先这样做在main.js中添加Date和String的扩展方法

效果图

在这里插入图片描述

-级联:做到监听 没大不有小
-添加表格空数据处理
-添加表格loadding加载
-分页总条数存至计算属性 一般不会变动则不吃消耗
-传参处理:使用计算属性传递参数 不会导致频繁访问data()中的内容 而且由于存在缓存所以请求效率会提高很多
-时间处理:使用组件封装的date.prototype使js date类型转yyyy-MM-dd
-表单校验
<template>
  <a-card :bordered="false">
    <div class="table-page-search-wrapper">
      <el-form :inline="true" :model="formObj" class="demo-form-inline" ref="ruleForm" :rules="formRules">
        <el-row>
          <el-col :span="8">
            <el-form-item label="创建时间" prop="queryTime">
              <el-date-picker
                v-model="formObj.queryTime"
                type="daterange"
                range-separator="-"
                start-placeholder="开始日期"
                end-placeholder="结束日期"
                size="mini"
              >
              </el-date-picker>
            </el-form-item>
          </el-col>
          <el-col :span="8">
            <el-form-item label="应出库时间" prop="queryTime2">
              <el-date-picker
                v-model="formObj.queryTime2"
                type="daterange"
                range-separator="-"
                start-placeholder="开始日期"
                end-placeholder="结束日期"
                size="mini"
              >
              </el-date-picker>
            </el-form-item>
          </el-col>
          <el-col :span="8">
            <el-form-item label="区域" prop="regionCode">
              <el-select
                v-model="formObj.regionCode"
                filterable
                remote
                reserve-keyword
                placeholder="请选择"
                @change="changeRegion"
                size="mini"
                clearable="true"
              >
                <el-option v-for="item in option3" :key="item" :label="item.label" :value="item.value"> </el-option>
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="8">
            <el-form-item label="库区" prop="areaCode">
              <el-select
                v-model="formObj.areaCode"
                filterable
                remote
                reserve-keyword
                placeholder="请选择"
                size="mini"
                clearable="true"
                :disabled="!this.formObj.regionCode"
              >
                <el-option v-for="item in option4" :key="item" :label="item.label" :value="item.value"> </el-option>
              </el-select>
            </el-form-item>
          </el-col>
        </el-row>
        <el-form-item>
          <el-button type="primary" @click="submitForm('ruleForm')">查询</el-button>
          <el-button @click="resetForm('ruleForm')">重置</el-button>
        </el-form-item>
      </el-form>
    </div>
    <!--api获取的参数绑定 prop->出参属性 label->对应中文名称-->
    <el-table border="true" :data="tableData" style="width: 100%" height="500" v-loading="loading" stripe size="small">
      <template slot="empty" v-if="!tableData.length">
        <span style="font-size: 20px">暂无数据</span>
      </template>
      <el-table-column prop="sum" label="" width="80"> </el-table-column>
      <el-table-column prop="whCode" label="仓库" width="100"> </el-table-column>
      <el-table-column prop="regionCode" label="区域" width="100"> </el-table-column>
      <el-table-column prop="areaCode" label="库区" width="100"> </el-table-column>
      <el-table-column prop="handoverCode" label="交接组" width="100"> </el-table-column>
      <el-table-column prop="yckTime" label="应出库时间" width="150"> </el-table-column>
      <el-table-column prop="yckqty" label="应出库单量" width="100"> </el-table-column>
      <el-table-column prop="pcQty" label="配车单量" width="100"> </el-table-column>
      <el-table-column prop="pcPercent" label="配车占比" width="100"> </el-table-column>
      <el-table-column prop="fpQty" label="分配单量" width="100"> </el-table-column>
      <el-table-column prop="fpPercent" label="分配占比" width="100"> </el-table-column>
      <el-table-column prop="yjQty" label="扫描单量" width="100"> </el-table-column>
      <el-table-column prop="yjPercent" label="扫描占比" width="100"> </el-table-column>
      <el-table-column prop="gzQty" label="记账单量" width="100"> </el-table-column>
      <el-table-column prop="gzPercent" label="记账占比" width="100"> </el-table-column>
      <el-table-column prop="fhQty" label="交接单量" width="100"> </el-table-column>
      <el-table-column prop="fhPercent" label="交接占比"> </el-table-column>
    </el-table>
    <el-row>
      <el-col :span="24">
        <div class="pagination-div">
          <el-pagination
            :hide-on-single-page="total >= pageSize ? false : true"
            @size-change="handleSizeChange"
            @current-change="handleCurrentChange"
            :current-page="pageNum"
            :page-sizes="[10, 20, 40]"
            :page-size="pageSize"
            layout="total, sizes, prev, pager, next"
            :total="total"
          >
          </el-pagination>
        </div>
      </el-col>
    </el-row>
  </a-card>
</template>

<script>
//单仓提货率报表
import { page } from '@/api/modular/handoverReport/handoverReportManage'

let myDate = new Date()

var createDateBegin = myDate
var createDateEnd = myDate
export default {
  data() {
    return {
      formObj: {
        queryTime: '',
        queryTime2:[createDateBegin,createDateEnd],
        bigYwlyCd: '',
        ywlyCd: '',
        areaCode: '',
        regionCode: '',
      },
      formRules: {
        queryTime2: [{ required: true, message: '应出库时间必选', trigger: 'change' }],
      },
      total: 0,
      pageSize: 10,
      pageNum: 1,
      loading: true,
      tableData: [],
      option3: [],
      option4: [],
    }
  },
  methods: {
   async getOption3() {
      //请求获得父级select-options
      //this.option3=[...res.data]
    },
  async  changeRegion(val) {
      this.getOption4(val)
    },
  async  getOption4(regionCode) {
    	//根据变动父级查询获得关联子集内容
    	//this.option4=[...res.data]
    },
    submitForm(formName) {
    this.$refs[formName].validate((valid) => {
        if (valid) {
          if (this.formObj.queryTime2) {
            this.getTableData(this.param)
          } else {
            this.$message.error('请选择时间区间')
          }
        } else {
          console.log('error submit!!')
          return false
        }
      })
    },
    resetForm(name) {
      this.$refs[name].resetFields()
      //重置表单时间需要单独处理
      this.formObj.queryTime = ''
      this.formObj.queryTime2 = [createDateBegin,createDateEnd]
      this.getTableData(this.param)
    },
    getTableData(param) {
      this.loading = true
      page(
        Object.assign({ pageNum: this.pageNum, pageSize: this.pageSize, whCode: this.$store.state.whCode }, param)
      ).then((res) => {
        this.tableData = res.data.records
        if (this.tableData.length) {
          this.tableData.push(res.data.totalMap)
        } else {
          this.pageNum = 1
        }
        this.totalCom(res.data.total)
        this.loading = false
      })
    },
    handleSizeChange(val) {
      this.pageSize = val
    },
    handleCurrentChange(val) {
      this.pageNum = val
    },
  },
  created() {
    this.getTableData(this.param)
    this.getOption()
    this.getOption3()
  },
  computed: {
    totalCom() {
      return function (val) {
        return (this.total = parseInt(val))
      }
    },
    param() {
      return {
        createDateBegin: this.formObj.queryTime?this.formObj.queryTime[0].Format('yyyy-MM-dd') : null,
        createDateEnd: this.formObj.queryTime?this.formObj.queryTime[1].Format('yyyy-MM-dd') : null,
        yckTimeBegin: this.formObj.queryTime2?this.formObj.queryTime2[0].Format('yyyy-MM-dd') : null,
        yckTimeEnd: this.formObj.queryTime2?this.formObj.queryTime2[1].Format('yyyy-MM-dd') : null,
        ywlyCd: this.formObj.ywlyCd,
        areaCode: this.formObj.areaCode,
        regionCode: this.formObj.regionCode,
      }
    },
  },
  watch: {
    pageSize(newVal) {
      this.getTableData(this.param)
    },
    pageNum(newVal) {
      this.getTableData(this.param)
    },
     "formObj.regionCode": {
      handler(newValue, oldValue) {
       
          this.formObj.areaCode = ''
        
      }
    },
     "formObj.bigYwlyCd": {
      handler(newValue, oldValue) {
         
          this.formObj.ywlyCd = ''
        
      }
    }
  },
}
</script>

<style lang="less">
* {
  margin: 0;
  padding: 0;
}
.el-range-editor--mini.el-input__inner {
  width: 240px;
}
.el-form-item__content {
  .el-input.el-input--mini.el-input--suffix {
    .el-input__inner {
      width: 240px;
    }
  }
  .el-input.el-input--mini {
    .el-input__inner {
      width: 240px;
    }
  }
}
.el-input.el-input--mini.el-input--suffix {
  .el-input__inner {
    width: 8em;
  }
}
.el-pagination {
  float: right;
}
</style>

上文中’handoverReportManage.js文件

import { axios } from '@/utils/request'

/**
 * 分页查询入库台数
 *
 * @author xhx
 * @date 2021/10/13 18:01
 */
export function page(parameter) {
    return axios({
        url: 'your url',
        method: 'post',
        data: parameter
    })
}

request.js

import Vue from 'vue'
import axios from 'axios'
import store from '@/store'
import { message, Modal, notification } from 'ant-design-vue' /// es/notification
import { VueAxios } from './axios'
import { ACCESS_TOKEN } from '@/store/mutation-types'

// 创建 axios 实例
const service = axios.create({
  baseURL: '/api', // api base_url
  timeout: 6000 // 请求超时时间
})

const err = (error) => {
    if (error.response) {
        const data = error.response.data
        const token = Vue.ls.get(ACCESS_TOKEN)

    if (error.response.status === 403) {
      console.log('服务器403啦,要重新登录!')
      notification.error({
        message: 'Forbidden',
        description: data.message
      })
    }
    if (error.response.status === 500) {
      if (data.message.length > 0) {
        message.error(data.message)
      }
    }
    if (error.response.status === 401 && !(data.result && data.result.isLogin)) {
      notification.error({
        message: 'Unauthorized',
        description: 'Authorization verification failed'
      })
      if (token) {
        store.dispatch('Logout').then(() => {
          setTimeout(() => {
            window.location.reload()
          }, 1500)
        })
      }
    }
  }
  return Promise.reject(error)
}

// request interceptor
service.interceptors.request.use(config => {
	//添加请求头
  //config.headers.Authorization =`Bearer ${store.state.token}`   
  //config.headers.userName=store.state.userName
    return config
}, err)

/**
 * response interceptor
 * 所有请求统一返回
 */
service.interceptors.response.use((response) => {
    if (response.request.responseType === 'blob') {
        return response
    }
    const code = response.data.code
    if (code === 1011006 || code === 1011007 || code === 1011008 || code === 1011009) {
        Modal.error({
            title: '提示:',
            content: response.data.message,
            okText: '重新登录',
            onOk: () => {
                Vue.ls.remove(ACCESS_TOKEN)
                window.location.reload()
            }
        })
    } else if (code === 1013002 || code === 1016002 || code === 1015002) {
        message.error(response.data.message)
        return response.data
    } else {
        return response.data
    }
}, err)

const installer = {
    vm: {},
    install (Vue) {
        Vue.use(VueAxios, service)
    }
}

export {
    installer as VueAxios,
    service as axios
}

上文涉及到三个文件,由于笔者封装了api 有一个.vue文件 两个.js文件,需要可以直接复用

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

商朝

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值