基于vant4封装日期时间选择器

1,202 阅读2分钟
  • vant4中日期和时间选择器是分开的

完整代码

<template>
  <div>
    <!-- 拜访时间 -->
    <van-popup v-model:show="popupShow" position="bottom" closeable>
      <div class="title">
        <span>{{ title }}</span>
      </div>
      <div class="flex_box">
        <van-date-picker v-model="dateData.currentDate" :min-date="dateData.minDate" :show-toolbar="false" :formatter="formatterDate" swipe-duration="250" />
        <van-time-picker v-model="dateData.currentTime" :show-toolbar="false" :formatter="formatterDate" swipe-duration="250" />
      </div>
      <div class="operation">
        <div @click="popupShow = false">取消</div>
        <div @click="timeConfirm">确定</div>
      </div>
    </van-popup>
  </div>
</template>
<script setup>
// eslint-disable-next-line no-unused-vars
const props = defineProps(['title']);
const popupShow = ref(false);
defineExpose({ popupShow });
const dateData = reactive({
  currentDate: formattedDate(new Date()).split('-'),
  minDate: new Date(2020, 0, 1),
  maxDate: new Date(),
  currentTime: formattedTime(),
  maxHour: new Date().getHours(),
  maxMinute: new Date().getMinutes(),
});
//格式化日期
const formatterDate = (type, option) => {
  if (type === 'year') {
    option.text += '年';
  }
  if (type === 'month') {
    option.text += '月';
  }
  if (type === 'day') {
    option.text += '日';
  }
  if (type === 'hour') {
    option.text += '时';
  }
  if (type === 'minute') {
    option.text += '分';
  }
  return option;
};
const emit = defineEmits(['timeConfirm']);
const timeConfirm = () => {
  popupShow.value = false
  let time = `${dateData.currentDate.join('-')}T${dateData.currentTime.join(':')}`;
  emit('timeConfirm', time);
};
// 日期处理
function formattedDate(date) {
  if (!date) return '';
  const today = date;
  const year = today.getFullYear();
  const month = String(today.getMonth() + 1).padStart(2, '0');
  const day = String(today.getDate()).padStart(2, '0');
  return `${year}-${month}-${day}`;
}
//时间处理
function formattedTime() {
  let now = new Date();
  let hours = now.getHours().toString().padStart(2, '0');
  let minutes = now.getMinutes().toString().padStart(2, '0');
  return [hours, minutes];
}
</script>
<style lang="scss" scoped>
::v-deep(.van-overlay) {
  background-color: rgba(0, 0, 0, 0.3);
}
::v-deep(.van-popup) {
  border-radius: 5px;
  .van-popup__close-icon {
    font-size: 19px;
  }
  .title {
    height: initial;
    color: #353639;
    font-weight: bold;
    font-size: 14px;
    padding: 20px 16px;
    span {
      padding-left: 4px;
    }
  }
  .flex_box {
    display: flex;
    .van-picker:nth-child(1) {
      flex: 2;
    }
    .van-picker:nth-child(2) {
      flex: 1;
    }
    .van-picker-column {
      font-size: 15px;
    }
  }
  .operation {
    padding: 16px 16px 24px;
    display: flex;
    border: 1px solid rgba(151, 151, 151, 0.1);
    box-shadow: 0px 2px 20px 0px rgba(95, 95, 95, 0.2);
    background-color: #ffffff;
    div {
      flex: 1;
      text-align: center;
      padding: 10px;
      border-radius: 5px;
      font-size: 15px;
    }
    div:nth-child(1) {
      color: #0052cc;
      border: 1px solid #0052cc;
      margin-right: 11px;
    }
    div:nth-child(2) {
      background-color: #0052cc;
      border: 1px solid #0052cc;
      color: #ffffff;
    }
  }
}
</style>
  • 在模板 (<template>) 部分:

    • 使用了 <van-popup> 组件来创建一个弹出式窗口,通过 v-model:show 来控制它的显示和隐藏。
    • 弹出窗口包含一个标题(<div class="title">)和一个日期选择器 (<van-date-picker>) 以及一个时间选择器 (<van-time-picker>)。
    • 在操作部分 (<div class="operation">) 有两个按钮,一个用于取消选择,另一个用于确认选择。
  • <script setup> 部分:

    • 通过 defineProps 获取了来自父组件的 title 属性,并创建了一个响应式的 popupShow 变量来控制弹出窗口的显示状态。
    • 使用 defineExpose 暴露了 popupShow 变量给父组件,以便父组件可以控制弹出窗口的显示。
    • 创建了一个名为 dateData 的响应式对象,其中包含了日期和时间选择器的数据,包括当前选择的日期和时间、最小日期、最大日期等。
    • 定义了 formatterDate 函数,用于格式化日期和时间选择器的选项。
    • 创建了一个 timeConfirm 函数,该函数在用户点击确认按钮时会被调用,用于处理用户的选择并将数据输出到控制台。
    • 定义了 formattedDateformattedTime 函数,用于格式化日期和时间数据。
  • 效果

图片.png

1695109913647.jpg