vue基于vant封装可精确到秒的时间选择器

前言

在移动开发中,时间选择的控件比比皆是,但却鲜有类似的组件可以精确到秒级别的,官方可能是考虑到小屏幕手机的显示问题,也可能是使用的场景寥寥无几,但是少不代表没有,所以最近花了点时间基于 vant 组件库封装了一个可以精确到秒级别的时间选择器。


实现思路

本章我们主要用到了 vant 组件库中的 Popup 弹出层组件搭配 DatetimePicker 组件进行时间选择。通过 propsemit 进行组件之间的通信。其实 vant 已经封装好一系列的代码了,我们需要修改的是自定义年月日时分秒的时间数据并将其添加到绑定的数组中即可。话不多说,下面直接看代码的实例。


封装文件

文件目录:src/components/timePicker

<template>
  <div>
    <!-- 弹出层 -->
    <van-popup get-container="body" v-model="isPicker" position="bottom" @close="confirmOn">
      <!-- 时间选择 -->
      <van-picker ref="picker" show-toolbar title="请选择时间" :columns="columns" @change="onChange" @cancel="cancelOn" @confirm="onConfirm" />
    </van-popup>
  </div>
</template>
<script>
export default {
  name: "popup",
  props: ["showPicker", "values"],
  data() {
    return {
      isPicker: false, //是否显示弹出层
      columns: [], //所有时间
      Mdays: "", //弹窗关闭时月份所在值
      Dindex: null,
    };
  },
  watch: {
    isPicker(val) {
      !val && this.$emit("changeValue");
      this.columns = [];
      this.getcolumns();
    },
    showPicker(val) {
      this.isPicker = val;
    },
    values(val) {
      if (val == "") {
        this.Mdays = "";
        this.Dindex = null;
      }
    },
  },
  methods: {
    getCountDays(year, month) {
      //获取某年某月多少天
      var day = new Date(year, month, 0);
      return day.getDate();
    },
    getcolumns() {
      var strtime = this.values;
      var date = new Date(strtime.replace(/-/g, "/"));
      var vmoduletime = date.getTime();
      if (this.values != "") {
        var vmoduledate = new Date(vmoduletime);
      } else {
        var vmoduledate = new Date(); //没有传入时间则默认当前时刻
      }
      var Y = vmoduledate.getFullYear();
      var M = vmoduledate.getMonth();
      var D = vmoduledate.getDate();
      var h = vmoduledate.getHours();
      var m = vmoduledate.getMinutes();
      var s = vmoduledate.getSeconds();
      var year = {}; //获取前后十年数组
      year.values = [];
      var Currentday = new Date().getFullYear();
      for (var i = Currentday - 10; i < Currentday + 10; i++) {
        year.values.push(i + "年");
      }
      year.defaultIndex = year.values.indexOf(Y + "年"); //设置默认选项当前年
      this.columns.push(year);
      var month = {}; //获取12月数组
      month.defaultIndex = M;
      month.values = Object.keys(Array.apply(null, { length: 13 })).map(
        function (item) {
          if (+item + 1 <= 10) {
            return "0" + item + "月";
          } else if (+item + 1 == 11) {
            return +item + "月";
          } else {
            return (+item + 0).toString() + "月";
          }
        }
      );
      month.values.splice(0, 1);
      this.columns.push(month);
      //获取当月的天数
      var days = this.getCountDays(Y, this.Mdays == "" ? M + 1 : this.Mdays);
      var day = {}; //创建当月天数数组
      day.defaultIndex = this.Dindex == null ? D - 1 : this.Dindex;
      day.values = Object.keys(Array.apply(null, { length: days + 1 })).map(
        function (item) {
          if (+item + 1 <= 10) {
            return "0" + item + "日";
          } else if (+item + 1 == 11) {
            return +item + "日";
          } else {
            return (+item + 0).toString() + "日";
          }
        }
      );
      day.values.splice(0, 1);
      this.columns.push(day);
      var hour = {}; //创建小时数组
      hour.defaultIndex = h;
      hour.values = Object.keys(Array.apply(null, { length: 24 })).map(
        function (item) {
          if (+item + 1 <= 10) {
            return "0" + item + "时";
          } else if (+item + 1 == 11) {
            return +item + "时";
          } else {
            return (+item + 0).toString() + "时";
          }
        }
      );
      this.columns.push(hour);
      var mi = {}; //创建分钟数组
      mi.defaultIndex = m;
      mi.values = Object.keys(Array.apply(null, { length: 60 })).map(function (
        item
      ) {
        if (+item + 1 <= 10) {
          return "0" + item + "分";
        } else if (+item + 1 == 11) {
          return +item + "分";
        } else {
          return (+item + 0).toString() + "分";
        }
      });
      this.columns.push(mi);
      var ss = {}; //创建秒数数组
      ss.defaultIndex = s;
      ss.values = Object.keys(Array.apply(null, { length: 60 })).map(function (
        item
      ) {
        if (+item + 1 <= 10) {
          return "0" + item + "秒";
        } else if (+item + 1 == 11) {
          return +item + "秒";
        } else {
          return (+item + 0).toString() + "秒";
        }
      });
      this.columns.push(ss);
    },
    onChange(values, a) {
      //a为所有列备选项值的数组
      var days = this.getCountDays(a[0].substr(0, 4), a[1].substr(0, 2));
      var newdays = {};
      newdays.values = Object.keys(Array.apply(null, { length: days + 1 })).map(
        function (item) {
          if (+item + 1 <= 10) {
            return "0" + item + "日";
          } else if (+item + 1 == 11) {
            return +item + "日";
          } else {
            return (+item + 0).toString() + "日";
          }
        }
      );
      newdays.values.splice(0, 1);
      this.$refs.picker.setColumnValues(2, newdays.values); //设置第三列的值
      this.$refs.picker.setColumnIndex(2, a[2].substr(0, 2) - 1); //设置第三列索引
    },
    // 关闭弹框
    confirmOn() {
      var currentM = this.$refs.picker.getColumnValue(1);
      this.Mdays = currentM.substr(0, 2);
      this.Dindex = this.$refs.picker.getColumnIndex(2);
    },
    //时间选择器关闭
    cancelOn() {
      this.$emit("changeValue");
    },
    // 时间选择器确定
    onConfirm(val, index) {
      var endval =
        val[0].substr(0, 4) +
        "-" +
        val[1].substr(0, 2) +
        "-" +
        val[2].substr(0, 2) +
        " " +
        val[3].substr(0, 2) +
        ":" +
        val[4].substr(0, 2) +
        ":" +
        val[5].substr(0, 2);
      this.$emit("changeValue", endval);
      this.$emit("confirm", endval);
    },
  },
};
</script>

使用组件

<template>
  <div>
    <div @click="revealOn">点击选择时间</div>
    <timePicker :values="timeVal" @changeValue="timePickerShow = false" ref="popup" :showPicker="timePickerShow" @confirm="confirmOn" />
  </div>
</template>
<script>
import timePicker from "@/components/timePicker";
export default {
  components: {
    timePicker,
  },
  data() {
    return {
      timeVal: "", //选中时间的值
      timePickerShow: false, //打开/关闭时间选择器
    };
  },
  methods: {
    // 点击选择时间
    revealOn() {
      this.timePickerShow = true;
    },
    // 时间选择器确定
    confirmOn(val) {
      console.log(val);
    },
  },
};
</script>

实现效果

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/1481.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

011+limou+C语言深入知识——(3)“字符串函数”和“字符分类函数”和“内存操作函数”以及“部分库函数的模拟实现”

一、字符串库函数 001、求字符串长度strlen size_t strlen ( const char * str );注意size_t是一个无符号类型&#xff0c;没有正负 #include <stdio.h> #include <string.h> int main() {char*str1 "abcdef";strcmpchar*str2 "bbb";if( …

《Roller: Fast and Efficient Tensor Compilation for Deep Learning》

《Roller: Fast and Efficient Tensor Compilation for Deep Learning》 用于深度学习 快速高效的张量编译器 作者 微软亚洲研究院以及多伦多大学等多所高校 摘要 当前编译为了产生高效的kernel时&#xff0c;搜索空间大&#xff0c;通常使用机器学习的方法 找到最优的方案…

【测试开发篇3】软件测试的常用概念

目录 一、软件测试的生命周期(5个步骤) ①需求分析(两个角度) 用户角度&#xff1a; 开发人员的角度&#xff1a; ②测试计划 ③测试设计、测试开发 ④执行测试 ⑤测试评估 二、软件测试贯穿项目的整个生命周期的体现 需求分析阶段 计划阶段 设计阶段 编码阶段 …

Keil5安装和使用小记

随着keil版本的更新&#xff0c;一些使用问题一随之产生。本文针对安装目前最新版本keil软件和使用问题做一些总结。 目录1 Keil5下载&安装1.1 官网下载链接1.2 软件安装1.2.1 安装说明1.2.2 关于 51 和 ARM 共存的问题1.3 软件破解2 pack包安装 & 破解2.1 下载2.2 安装…

智能生活垃圾检测与分类系统(UI界面+YOLOv5+训练数据集)

摘要&#xff1a;智能生活垃圾检测与分类系统用于日常生活垃圾的智能监测与分类&#xff0c;通过图片、视频和摄像头识别生活垃圾&#xff0c;对常见的可降解、纸板、玻璃、金属、纸质和塑料等类别垃圾进行检测和计数&#xff0c;以协助垃圾环保分类处理。本文详细介绍基于YOLO…

找一找马里奥-第14届蓝桥杯STEMA测评Scratch真题精选

[导读]&#xff1a;超平老师的《Scratch蓝桥杯真题解析100讲》已经全部完成&#xff0c;后续会不定期解读蓝桥杯真题&#xff0c;这是Scratch蓝桥杯真题解析第110讲。 蓝桥杯选拔赛现已更名为STEMA&#xff0c;即STEM 能力测试&#xff0c;是蓝桥杯大赛组委会与美国普林斯顿多…

《Linux的权限》

本文主要对linux的一些基本权限进行讲解 文章目录前言Linux权限&#xff08;1&#xff09;权限的概念&#xff08;2&#xff09;linux下用户分类(root,普通)(3)linux的文件属性文件属性的分类文件权限修改文件权限1、chmod2、chown和chgrp3、fiile权限的三个重要的问题第一个问…

Java面向对象:接口的学习

本文介绍了Java中接口的基本语法, 什么是接口, java中的接口 语法规则, 接口的使用,接口的特性,如何实现多个接口,接口间的继承,以及抽象类和接口的区别 Java接口的学习一.接口的概念二.Java中的接口1.接口语法规则2.接口的使用3.接口的特性4.实现多个接口5.接口间的继承三.抽象…

C++线程池理解

线程池基本信息 线程池是一种结合池化思想衍生出来的一种线程管理及使用的方案 其主要针对服务器端多线程场景下&#xff0c;服务器频繁接收请求&#xff0c;每个请求都分配一个单独的线程去处理。 使用线程的开销&#xff1a; 创建和销毁线程调度线程 线程池主要解决的核…

你是真的“C”——结构体中鲜有人知的“秘密”

你是真的“C”——结构体中的精髓剖析【内存对齐】 【位段】 &#x1f60e;前言&#x1f64c;结构体内存对齐&#xff1a;&#x1f60a;结构体内存对齐存在的意思是什么&#xff1f;&#x1f618;内存对齐例子详细剖析&#xff1a;&#x1f618;结构体中的位段&#xff1a;&…

基于Vue+Vue-cli+webpack搭建渐进式高可维护性前端实战项目

本文是专栏《Vue SpringBoot前后端分离项目实战》的实战第一篇&#xff0c;将从Vue脚手架安装开始&#xff0c;逐步带你搭建起一套管理系统所需的架构。当然&#xff0c;在默认安装完成之后&#xff0c;会对文件目录进行初步的细化拆分&#xff0c;以便后续功能迭代和维护所用…

ChatGPT没有API?OpenAI官方API带你起飞

目录ChatGPT没有API&#xff1f;OpenAI官方API带你起飞安装 OpenAI 的 API 库包装个函数包装个UIAPI 调不通怎么办&#xff1f;ChatGPT没有API&#xff1f;OpenAI官方API带你起飞 前段时间ChatGPT爆火&#xff0c;OpenAI 的 GPT API也被大家疯狂调用&#xff0c; 但其实这个AP…

超详细的堆排序,进来看看吧。

1.堆的基本概念1.1什么是堆堆是一种叫做完全二叉树的数据结构&#xff0c;1.2大堆和小堆大堆:每个节点的值都大于或者等于他的左右孩子节点的值小根堆:每个结点的值都小于或等于其左孩子和右孩子结点的值1.3完全二叉树节点之间的关系leftchild parent*2 1rightchild parent*…

string类(上)

string类&#xff08;上&#xff09;1.标准库中的string类2.string类对象的常见构造①string()②string(const char* s)③string(size_t n,char c)④string(const string&s)⑤string(const string& str,size_t pos,size_t lennpos)⑥string&#xff08;const char* s,s…

【基于协同过滤算法的推荐系统项目实战-2】了解协同过滤推荐系统

本文目录1、推荐系统的关键元素1.1 数据1.2 算法1.3 业务领域1.4 展示信息2、推荐算法的主要分类2.1 基于关联规则的推荐算法基于Apriori的算法基于FP-Growth的算法2.2 基于内容的推荐算法2.3 基于协同过滤的推荐算法3、推荐系统常见的问题1、冷启动2、数据稀疏3、不断变化的用…

java 每日一练 (9)

文章目录1. 单选2. 编程1. 单选 1. 下面程序的输出是:() A &#xff1a; FmNwxy B &#xff1a;fmnwxy C &#xff1a;wxyfmn D &#xff1a; Fmnwxy 答案 &#xff1a; D &#xff0c; 这里主要考察 toUpperCase 和 replace 方法 &#xff0c; 注意点 &#xff1a; toUpperCas…

动态规划-基础(斐波那契数、爬楼梯、使用最小花费爬楼梯、不同路径、不同路径II、整数拆分、不同的二叉搜索树)

动态规划&#xff0c;英文&#xff1a;Dynamic Programming&#xff0c;简称DP&#xff0c;如果某一问题有很多重叠子问题&#xff0c;使用动态规划是最有效的。所以动态规划中每一个状态一定是由上一个状态推导出来的。动态规划问题&#xff0c;五步走&#xff1a;状态定义&am…

【数据结构】双向链表

&#x1f680;write in front&#x1f680; &#x1f4dc;所属专栏&#xff1a; 初阶数据结构 &#x1f6f0;️博客主页&#xff1a;睿睿的博客主页 &#x1f6f0;️代码仓库&#xff1a;&#x1f389;VS2022_C语言仓库 &#x1f3a1;您的点赞、关注、收藏、评论&#xff0c;是…

海思SD3403/SS928V100开发(7)mcp2515-SPI转CAN驱动开发

1. 前言 需求: 需要一路can进行收发 分析: 根据目前使用较多的方案是使用主控端SPI接口 接入MCP2515芯片进行CAN协议转换 硬件: MCP2515->SPI2->SS928 2. Uboot开发 2.1 pinmux复用配置 2.1.1 修改uboot参数表 路径: osdrv/tools/pc/uboot_tools/ SS928V100…

Android 进程间通信机制(三) 系统进程与应用进程通信

一. 概述 Android中有一个重要的系统进程(system_server)&#xff0c;运行着系统中非常重要服务(AMS, PMS, WMS等)&#xff0c; 针对Activity而言&#xff0c;系统进程需要不断地调度Activity执行&#xff0c;管理Activity的状态; 每一个APK都需要运行在一个应用进程中&#xf…