Vant 日期时间组件拓展

news/2024/10/16 22:18:12 标签: 前端, javascript, html
htmledit_views">

基于 

"vant": "^4.8.3",

效果图

html" title=javascript>javascript"><template>
    <!-- 弹出层 -->
    <van-popup
        v-model:show="isPicker"
        position="bottom"
    >
      <van-picker
          ref="picker"
          :title="title"
          v-model="selectedValues"
          :columns="columns"
          @change="onChange"
          @cancel="cancelOn"
          @confirm="onConfirm"
      />
    </van-popup>
</template>

js

html" title=javascript>javascript"><script setup lang="ts">
import { ref ,watch } from 'vue';
import {formatTimeArray} from "@/utils/formate/date_formate";

const props = defineProps({
  showPicker: {
    type: Boolean,
    default: false,
  },
  title: {
    type: String,
    default: "请选择时间",
  },
  timeFormat: {
    type: String,
    default: "yyyy-MM-dd HH:mm:ss",
  },
})

const  isPicker = ref<any>(false) //是否显示弹出层
const  columns = ref<any>([])
const picker = ref()
const getCountDays = (year: any, month: any) => {
  //获取某年某月多少天
  const day = new Date(year, month, 0);
  return day.getDate();
}

const selectedValues = ref<any>(formatTimeArray(new Date()));

const getColumns = () => {
  const Y: any = selectedValues.value[0];
  const M: any = selectedValues.value[1];

  let year: any = []; // 默认范围 前后十年
  for (let i = Y - 10; i <= Y + 10; i++) {
    year.push({text: i,value: i});
  }

  let month: any ;//月
  month = getColumn(13,true)

  let days: any = getCountDays(Y, M); //天,和当年月有关
  let day: any;
  day = getColumn(days + 1,true)

  let hour: any ; //小时
  hour = getColumn(24)

  let minute: any ; //分钟
  minute = getColumn(60)

  let seconds: any ; //秒
  seconds = getColumn(60)

  if (props.timeFormat?.includes("yyyy")) {
    columns.value.push(year);
  }
  if (props.timeFormat?.includes("MM")) {
    columns.value.push(month); //获取当月的天数
  }
  if (props.timeFormat?.includes("dd")) {
    columns.value.push(day);
  }
  if (props.timeFormat?.includes("HH")) {
    columns.value.push(hour);
  }
  if (props.timeFormat?.includes("mm")) {
    columns.value.push(minute);
  }
  if (props.timeFormat?.includes("ss")) {
    columns.value.push(seconds);
  }
}

const getColumn = (length: any,isSplice: Boolean = false) => {
  if ( isSplice ) {
    const data = Array.from({ length }, (_, index) => ({ text: index, value: index }));
    return data.splice(1)
  } else {
    return Array.from({ length }, (_, index) => ({ text: index, value: index }));
  }
}

const onChange = (values: any) => {
  let days: any = getCountDays(values.selectedValues[0], values.selectedValues[1]);
  let newDayColumn: any ;
  newDayColumn = getColumn(days + 1,true);
  columns.value[2] = newDayColumn
}

const emits = defineEmits(["changeValue",'confirm']);

const cancelOn = () => {
  emits("changeValue");
};

const onConfirm = (val: any) => {
  let endVal: any = "";
  for (let i = 0; i < columns.value.length; i++) {
    endVal += val[i];
    if ( i === 2 ) {
      endVal += " ";
    } else if (i >= 3 && i <= 5) {
      endVal += ":";
    } else if (i < columns.value.length - 1) {
      endVal += "-";
    }
  }
  // 判断最后一个字符是否是分隔符
  if (endVal.endsWith("-") || endVal.endsWith(":")) {
    endVal = endVal.slice(0, -1); // 删除最后一个字符
  }
  emits("changeValue", endVal);
  emits("confirm", val.selectedValues);

}

// 监听 isPicker 的变化
watch(isPicker, (val: any) => {
  if (!val) {
    emits("changeValue");
  }
  columns.value = [];
  getColumns();
});

// 监听 showPicker 的变化
watch(() => props.showPicker, (val) => {
  isPicker.value = val;
});


</script>

引用组件

html" title=javascript>javascript"> <DateTimePicker
          @changeValue="showEndPicker = false"
          ref="popup"
          :showPicker="showEndPicker"
          @confirm="onEndConfirm"
      />

结合 输入框一起使用

html" title=javascript>javascript">      <van-field
          class="form-wrapper"
          v-model="formData.pzzy_enddate"
          is-link
          required
          label-width="130"
          name="datePicker"
          label="批准作业结束时间"
          placeholder="点击选择时间"
          @click="showEndPicker = true"
      />
      <DateTimePicker
          @changeValue="showEndPicker = false"
          ref="popup"
          :showPicker="showEndPicker"
          @confirm="onEndConfirm"
      />


http://www.niftyadmin.cn/n/5708619.html

相关文章

关于移动通信网络中各个组成部分的基础入门

移动通信网络的详细组成 移动通信网络是一个复杂的系统&#xff0c;由多个层次和组件构成&#xff0c;每个组件都有其特定的功能和作用。以下是对移动通信网络各个组成部分的详细阐述&#xff1a; 1. 终端设备&#xff08;End User Devices&#xff09; 定义&#xff1a; 终…

【返璞归真】-泰勒展开式

泰勒展开式是将一个函数在某点附近展开为一个无穷级数的方式&#xff0c;其原理是通过函数在该点的导数来近似函数值。公式为&#xff1a; f ( x ) f ( a ) f ′ ( a ) ( x − a ) f ′ ′ ( a ) 2 ! ( x − a ) 2 f ′ ′ ′ ( a ) 3 ! ( x − a ) 3 ⋯ f(x) f(a) f(a)…

架构设计笔记-11-未来信息综合技术

知识要点 云原生架构原则包括&#xff1a;服务化原则、弹性原则、可观测原则、韧性原则、所有过程自动化原则、零信任原则和架构持续演进原则。 区块链是一种按照时间顺序将数据区块以顺序相连的方式组合成的一种链式数据结构&#xff0c;并以密码学方式保证的不可篡改和不可…

Vue3使用element plus时el-menu导航选中后刷新页面及修改URL无法保持当前选中状态问题

问题1: 在使用element plus的el-menu菜单导航时&#xff0c;发现选中后刷新高亮部分无法保持当前选择状态 解决方法: 因为刷新页面后el-menu的:default-active"activeIndex"被刷新&#xff0c;无法记录所以导致高亮部分无法保持选择状态 所以为了保持下来这个值&…

mysql 09 独立表空间结构

表空间中的页实在是太多了&#xff0c;为了更好的管理这些页面&#xff0c;设计 InnoDB 的大叔们提出了 区 &#xff08;英文名&#xff1a; extent &#xff09;的概念。对于16KB的页来说&#xff0c;连续的64个页就是一个 区 &#xff0c;也就是说一个区默认占用1MB空间大小。…

网络爬虫-数美滑块验证码

仅供研究学习使用。 今天带来的是数美滑块验证码的逆向 目标站 --> 传送门 解决此类验证码 首先要解决滑动距离的判定 无论是使用selenium还是使用协议的方式来破解 都绕不开滑动距离的识别 滑动距离可以参考以前我博客上的方式&#xff0c;或者找一找开源的一些算法&am…

C++进阶 AVL树的讲解以及实现

你好&#xff0c;欢迎阅读我的文章~ 个人主页&#xff1a;Mike 所属专栏&#xff1a;C进阶 目录 1. AVL的概念 2.AVL树的实现 2.1AVL树的结构 2.2AVL树的插入 2.2.1 插入的过程 2.2.2 平衡因子的更新 2.2.3 更新停止的条件 插入节点以及更新平衡因子的源码 3.AVL的旋…

Unity3D模型消融方法(一)

系列文章目录 unity工具 文章目录 系列文章目录👉前言👉一、消融效果👉二、使用步骤👉2-1.交互代码2-2. 完整shader代码👉2-3 新建材质球👉壁纸分享👉总结👉前言 今天介绍一下模型消融效果(shader实现) 还有另外一种换shader实现 大家好,我是心疼你的一切,…