vue 时间选择器和分页的组合-前后端代码实践

/ vue / 没有评论 / 2115浏览

环境

UI : element ui

Vue: 2.6

Django:3.1.4

Demo

背景

当前时间选择器主要有两种状态

  1. 用户选择时间,有值;

  2. 用户清除时间,值为null。

有值啥都好说,没值的话,前端不做空值处理,会报错,后端Django orm 查询时间区间也会报错,我们要充分考虑可能发生的异常。

意味着要做两次异常处理,一次是前端清除选择,一次是后端判断前端URL传空值的校验

时间选择器每次产生值,都要从第一页开始,重置当前页面为1,保证分页查询不超出后端分页范围

原理图

前端代码

template

<el-col :span="5">
  <div class="block">
  <el-date-picker @change="selectTime" v-model="TimeSelect.SelectTimeValue" type="daterange" align="right" format="yyyy-MM-dd" value-format="yyyy-MM-dd" unlink-panels range-separator="至"
    start-placeholder="开始日期"
    end-placeholder="结束日期"
    :picker-options="pickerOptions">
  </el-date-picker>
  </div>
  </el-col>

scripts - data

data() {
  return {
    TimeSelect: {
      SelectTimeValue: ''
    },
    pickerOptions: {
      shortcuts: [{
        text: '最近一周',
        onClick(picker) {
          const end = new Date();
          const start = new Date();
          start.setTime(start.getTime() - 3600 * 1000 * 24 * 7);
          picker.$emit('pick', [start, end]);
        }
      }, {
        text: '最近一个月',
        onClick(picker) {
          const end = new Date();
          const start = new Date();
          start.setTime(start.getTime() - 3600 * 1000 * 24 * 30);
          picker.$emit('pick', [start, end]);
        }
      }, {
        text: '最近三个月',
        onClick(picker) {
          const end = new Date();
          const start = new Date();
          start.setTime(start.getTime() - 3600 * 1000 * 24 * 90);
          picker.$emit('pick', [start, end]);
        }
      }]
    },
    receiverInfos: [],
    SelectDataListTpl:{project_name:''},
    currentPage: 1, //默认显示页面为1
    pagesize: 10, //    每页的数据条数
    total:0
  };
},

scripts - methods

methods: {
  // 时间选择器
  selectTime(val){
    if (this.TimeSelect.SelectTimeValue === null) {
      this.getReceiverInfos()
    }else {
      this.TimeSelect.SelectTimeValue = val;
      console.log(val);
      this.loading=true
      this.$http({
        method: "get",
        url: "/api/AllSelectAllPublicPageProjectDateSelect",
        params: {
          currentpage: this.currentPage,
          pagesize:this.pagesize,
          startDate:val[0],
          endDate:val[1]
        },
      })
        .then(result => {
          this.loading=false
          this.total = result.data.total;
          this.receiverInfos = result.data.data;
        })
        .catch(err => {
          console.dir(err);
        });
    }
  }, 
  // table 数据
  getReceiverInfos() {
  if (this.TimeSelect.SelectTimeValue === null){
    this.TimeSelect.SelectTimeValue = []
  }
  this.currentPage = 1
  this.loading=true
  this.$http({
    method: "get",
    url: "/api/url",
    params: {
      currentpage: 1,
      pagesize:this.pagesize,
      startDate: this.TimeSelect.SelectTimeValue[0],
      endDate: this.TimeSelect.SelectTimeValue[1]
    },
  })
    .then(result => {
      this.loading=false
      this.total = result.data.total;
      this.receiverInfos = result.data.data;
    })
    .catch(err => {
      console.dir(err);
    });
},
}
}; 

后端代码

class AllSelectAllPublicPageProjectDateSelect(APIView):
    def get(self, request, format=None):
        response = {
            'code': HTTP_200_OK,
            'msg': '查询成功',
            'data': [],
            'total': int
        }
        start_date = request.GET.get('startDate')
        end_date = request.GET.get('endDate')
        if start_date is None:
            queryset = PublicPage.objects.filter(project_delete=0).order_by(
                "-update_time")
        else:
            queryset = PublicPage.objects.filter(project_delete=0, create_time__range=(start_date, end_date)).order_by(
                "-update_time")
        SelectPublicPageDataTotal = queryset.count()
        page_obj = MyPageNumber()
        page_PublicPageData = page_obj.paginate_queryset(queryset=queryset, request=request, view=self)
        ser_obj = publicPageSerializer(page_PublicPageData, many=True)
        response['data'] = ser_obj.data
        response['total'] = SelectPublicPageDataTotal
        return Response(response, status=200)