vant Time Selector Start Time and End Time Instances

  • 2021-09-12 00:08:56
  • OfStack

I won't talk too much, let's just look at the code ~


<template>
  <div class="linesMigrate">
    <div class="conditionDiv">
      <div class="singleCondition" :style="conditonStyle2" @click="showPopupDateChooseStart">
        <div class="dateValueDiv" v-if="allDateStart">{{dateFormatterStart}}</div>
        <div class="dateValueDiv" v-if="!allDateStart" :style="{ fontSize:'0.72rem' }">{{dateFormatterStart}}</div>
      </div>
      <div class="singleCondition" :style="conditonStyle2" @click="showPopupDateChoose">
        <div class="dateValueDiv" v-if="allDate">{{dateFormatter}}</div>
        <div class="dateValueDiv" v-if="!allDate" :style="{ fontSize:'0.72rem' }">{{dateFormatter}}</div>
      </div>
    </div>
    <!-- 选开始时间 -->
    <van-popup
        v-model="showDateChooseStart"
        position="bottom"
        :close-on-click-overlay="false"
        :style="{ height: '22rem',position: 'absolute',bottom:'3rem' }"
        :overlay-style="{ position: 'absolute', bottom: '3rem', top: 'auto', background: 'rgba(0, 0, 0, 0.298039215686275)' }">
      <div class="popupDate" :style="bgDateImgStyle">
      <img alt="..." src="../../assets/icon/downArrow.png" @click="closeDatePopStart" :style="{ marginBottom: '16%',width:'10%',marginTop:'7.7%',opacity:0 }" />
      <van-datetime-picker
          :show-toolbar="false"
          v-model="dateChooseStart"
          type="date"
          :min-date="minDateStart"
          :max-date="maxDateStart"
      />
        <div class="chooseTodayDiv" @click="chooseDateStart">选择最近1周</div>
      </div>
    </van-popup>
    <!-- 选结束时间 最近1天 -->
    <van-popup
        v-model="showDateChoose"
        position="bottom"
        :close-on-click-overlay="false"
        :style="{ height: '22rem',position: 'absolute',bottom:'3rem' }"
        :overlay-style="{ position: 'absolute', bottom: '3rem', top: 'auto', background: 'rgba(0, 0, 0, 0.298039215686275)' }">
      <div class="popupDate" :style="bgDateImgStyle">
      <img alt="..." src="../../assets/icon/downArrow.png" @click="closeDatePop" :style="{ marginBottom: '16%',width:'10%',marginTop:'7.7%',opacity:0 }" />
      <van-datetime-picker
          :show-toolbar="false"
          v-model="dateChoose"
          type="date"
          :min-date="minDate"
          :max-date="maxDate"
      />
        <div class="chooseTodayDiv" @click="chooseDateToday">选择最新1天</div>
      </div>
    </van-popup>
 

    <Loading :isShow="loadingState" />
  </div>
</template>
 

<script>
  import Loading from '../../components/common/loading.vue';// 引入公共的loading组件
  import Vue from 'vue';
  import { Popup } from 'vant';
  import { DatetimePicker } from 'vant';
  
  Vue.use(DatetimePicker);
  Vue.use(Popup);
 

  export default {
    name: 'lines',
    mounted() {
      // 获取数据
      this.loadingState=false;
      this.initRequest();
    },
    data() {
      return {
        // 时间选择背景样式数据
        conditonStyle2: {
          background: "url(" + require("../../assets/img/migrate2.png") + ") no-repeat center",
          backgroundSize: "contain"
        },
        // 日期组件弹出层展示与否的标志 --开始时间
        showDateChooseStart:false,
         // 日期组件弹出层展示与否的标志
        showDateChoose:false,
        
        // 弹出层背景图片
        bgDateImgStyle: {
          background: "url(" + require("../../assets/img/migratePopBackDate.png") + ") no-repeat",
          backgroundSize: "contain"
        },
        // 标准化未经处理的时间格式
        dateChoose: new Date(),
        dateChooseStart: new Date(),
        // 处理过格式的日期数据
        dateFormatter:"日期",
        allDate:true,
        dateFormatterStart:"日期",
        allDateStart:true,
 

        minDateStart: new Date(2019,8,1), // 开始时间最小2019/9/01
        maxDateStart: new Date(), // 开始时间最大 当前时间
        minDate: new Date(), //最小时间必须 》开始的最大时间maxDateStart 
        maxDate: new Date(), // 开始时间最大 当前时间
 

        // 控制加载中状态的标志
        loadingState:true
      };
    },
    methods: {
      // 初始的请求方法
      async initRequest(){
        this.chooseDateToday();
        this.chooseDateStart();
      },
      // 展示日期弹出层--开始时间
      showPopupDateChooseStart() {
        this.showDateChooseStart = true;
      },
      // 展示日期弹出层 --结束时间
      showPopupDateChoose() {
        // 设置结束时间的最小值
        this.minDate = this.dateChooseStart;
        this.showDateChoose = true;
      },
      
      // 关闭日期弹出层 ---开始时间
      closeDatePopStart(){
        this.showDateChooseStart = false;
        this.dateFormatterStart=this.dateTransfor(this.dateChooseStart,"yyyy-MM-dd");
 

        // 设置结束时间的最小值
        this.minDate = this.dateChooseStart;
 

        this.allDateStart=false;
        // this.loadingState=true;
      },
      // 关闭日期弹出层 --结束时间
      closeDatePop(){
        this.showDateChoose = false;
        this.dateFormatter=this.dateTransfor(this.dateChoose,"yyyy-MM-dd");
 

        // 设置开始时间的最大值
        this.maxDateStart = this.dateChoose;
 

        this.allDate=false;
        // this.loadingState=true;
      },
      
      // 日期格式转换函数
      dateTransfor(date,format){
        var o = {
          "M+" : date.getMonth()+1,         //月份
          "d+" : date.getDate(),          //日
          "h+" : date.getHours(),          //小时
          "m+" : date.getMinutes(),         //分
          "s+" : date.getSeconds(),         //秒
          "q+" : Math.floor((date.getMonth()+3)/3), //季度
          "S" : date.getMilliseconds()       //毫秒
        };
        if(/(y+)/.test(format)) {
          format=format.replace(RegExp.$1, (date.getFullYear()+"").substr(4 - RegExp.$1.length));
        }
        for(let k in o) {
          if(new RegExp("("+ k +")").test(format)){
            format = format.replace(RegExp.$1, (RegExp.$1.length==1) ? (o[k]) : (("00"+ o[k]).substr((""+ o[k]).length)));
          }
        }
        return format;
      },
      // 选择时间函数 -- 7天前
      chooseDateStart(){
        let yesToday=new Date();
        yesToday.setDate(yesToday.getDate()-7);
        this.dateChooseStart=yesToday;
        this.dateFormatterStart=this.dateTransfor(this.dateChooseStart,"yyyy-MM-dd");
      },
      // 选择时间函数 -- 今日
      chooseDateToday(){
        this.dateChoose= new Date();
        this.dateFormatter=this.dateTransfor(this.dateChoose,"yyyy-MM-dd");
      },
      // 选择时间函数 i=0今日
      chooseDate(i){
        let yesToday=new Date();
        yesToday.setDate(yesToday.getDate()-i);
        return this.dateTransfor(yesToday,"yyyy-MM-dd");
      },
 

    },
    components: {
      Loading
    }
  };
</script>
<style scoped>
  /*覆盖原有弹出层样式*/
  .van-popup {
    position: absolute;
    background: transparent;
    /*bottom: 3.01rem;*/
  }
  /*覆盖日期组件原有样式*/
  .van-picker{
    position: relative;
    background-color: #fff;
    user-select: none;
    width: 100%;
  }
 
  /*筛选条件们的div样式*/
  .conditionDiv{
    display: flex;
    justify-content: center;
    width: 100%;
    height: 3.7%;
    margin-top: 4%;
  }
  /*单个筛选条件的样式*/
  .singleCondition{
    width: 27%;
    margin-left: 2%;
    margin-right: 2%;
    /*border: 1px solid #451da4;*/
    height: 100%;
    /*padding-right: 5%;*/
    color: #fff;
    display: flex;
    justify-content: center;
    align-items: center;
    /*flex-direction: column;*/
    font-size: 0.72rem;
  }
  /*日期组件的div,由于其背景用icon而非整个背景图,因此样式上不同*/
  .singleDateDiv{
    width: 23%;
    margin-left: 2%;
    margin-right: 2%;
    /*border: 1px solid #451da4;*/
    height: 100%;
    color: #fff;
    padding-right: 5%;
    display: flex;
    justify-content: flex-start;
  }
  /*日期的值位置样式*/
  .dateValueDiv{
    display: flex;
    justify-content: center;
    flex-direction: column;
    font-size: 0.72rem;
    width: 82%;
  }
  /*日期弹出层中选择今天div样式*/
  .chooseTodayDiv{
    box-sizing: border-box;
    z-index: 2;
    display: flex;
    justify-content: center;
    align-items: center;
    position: absolute;
    bottom: 0;
    color: red;
    height: 3rem;
    width: 90%;
    background: #fff;
    border-top: 1px solid lightgrey;
    font-size: 0.875rem;
  }
  
  /*日期弹窗*/
  .popupDate {
    border-radius: 2px;
    background: #fff;
    height: 100%;
    width: 90%;
    margin: 0 auto;
  }
 

</style>
<style>
  /*覆盖原有的选择器样式*/
  .van-picker-column{
    font-size: 0.9rem;
  }
</style>

Supplementary knowledge: the use of Vant library, and some attention points of date component

The Vant library is really very nice for developers' urban projects, which will make you fall in love with it. Vant library supports on-demand loading, and the style designed for mobile shopping malls is perfect. However, in the actual development, I also encountered some small problems, which were tossed for a long time and finally solved.

Let's talk about the process of using Vant library in vue and some precautions, as well as the pits encountered and solutions.

First, send it to the portal of official website: www. youzanyun. com/zanui/vant # …, and the specific api can be consulted and used by yourself.

Step 1, Install:

cnpm i vant -S

Step 2, introduce components:

There are two ways to introduce Vant components: global introduction (highly discouraged) and on-demand introduction

Here, we demonstrate the way of introducing on demand, because what official website said is a little complicated, which may cause some misunderstandings for some new friends (PS: I squatted in two pits here when I first started to contact, and I almost wanted to cry without tears ~). Just say how to use it:

In order to facilitate us to introduce components on demand, we also need to install a plug-in here

cnpm i babel-plugin-import -D

To install the plug-in, you need to make a simple configuration in plugins in the. babelrc file, and attach the complete plugins part here. Here we insert the import array into the plugins array, and the rest is already there.


"plugins": [  
  "transform-vue-jsx",   
  "transform-runtime",  
  ["import", {   
    "libraryName": "vant",   
    "libraryDirectory": "es",   
    "style": true  
  }]
]

After the configuration is complete, introduce the components you need as needed in main. js. For example, the button component of Vant is introduced here:


import { Button } from 'vant'; //  In mian.js Passed in import Import components, multiple components directly in the { ,,, } Add in 
Vue.use(Button); // Jean vue If you need to use other components to load this component, you can write Vue.use(Button).use().user();
<van-button type="default"> Default button </van-button> //  In template Use components in 

One point is mentioned here. If it is a component like Toast, it only needs to be introduced in main. js:


import { Toast } from 'vant';
 
//  Then use it directly on the page you need 
//  As long as it is introduced, vant It will automatically put Toast Component hangs on the vue On the prototype of Vue.prototype.$Toast = Toast;
this.$Toast('message');

As you can see, the button component and normal import are used here. There are more functional components suitable for actual development in Vant. Please refer to the official documents for your own use.

Attached to official website API document portal: www.youzanyun.com/zanui/vant # …

Finally, I talk about a big hole encountered when using Vant date component.

The official website api of Vant date component did not give demo about the use of event function, and then this site accidentally stepped into a big pit when using it.

That is, when change or confirm events, you can't get callback parameters, that is, when you click OK, you can't return to the selected time, and you will always prompt undefined or null. The following is the wrong writing of this site, so don't step on the pit:


<!-- This is html Department -->
<van-datetime-picker   
  v-model="currentDate"   
  type="datetime"   
  @confirm="confirm()"   
  @change="change()" />
 
//  This is the corresponding method 
methods: {
  confirm(val) {
    console.log(val)
  },
  change(e) {
    console.log(e.getValues())
  }
}

At first glance, it is used in the way stated in the document, but not only does confirm not return the selected date and time, but also various callback methods of change events cannot be used.

But if you want to print 1, you can print it again, indicating that the interface goes this way.

What's going on? Why can't you get out of the selected time? This site almost wonders if there is something wrong with this Vant component!

Get to the point: Later, this site finally found a solution:

It turns out that there is something wrong here, @ confirm= "confirm ()" @ change= "change ()"

There is an extra pair of brackets here. The correct way to write it is


<!-- This is html Part -->
<van-datetime-picker   
  v-model="currentDate"   
  type="datetime"   
  @confirm="confirm"   
  @change="change" 
/>
 
//  This is the corresponding method 
methods: {
  confirm(val) {
    console.log(val) //  Printed out the time 
  },
  change(e) {
    console.log(e.getValues()) //  Printed out the selected time, which is an array 
  }
}

Here, the problem has been solved satisfactorily!


Related articles: