vue3 实现一个年月日时分秒的时间组件

就是项目是app的,有这么一个需求,我要展示一个时间组件,格式是YYYY-MM-DD HH:mm:ss,但因为项目没引入monment.js,所以我是一点点转换的,其中也借鉴了别人的代码,借鉴文章地址vue3+vant4封装日期时间组件(年月日时分秒)_vant4 年月日时分秒-CSDN博客。稍作改动,我们的需求是如果我传入一个YYYY-MM-DD HH:mm:ss格式的时间,则单元格反显这个时间,要是没传入,那就展示当前默认时间。效果如下 ,这个2022巴拉巴拉的就是传入的时间。父组件不传,就显示默认的就行啦。

下面就是完整代码:
 

<!--
 * @Description: 年月日时分秒时间选择组件 
 * @FilePath: \shared\common\src\components\DateTimePicker
-->
<template>
  <!-- 参数说明
  /**
  *  |-Params[cellTitle] {String} 单元格名称 默认时间 (必传)
  *  |-Params[values] {String} 传入的时间值 格式为YYYY-MM-DD HH:mm:ss (必传)
  *  示例:<DateTimePicker :cellTitle="'创建时间'" :values="''"/>
  */
  -->
  <van-cell
    :title="cellTitle"
    is-link
    :value="values"
    @click="showPopup"
  />
  <van-popup
    v-model:show="data.isPicker"
    position="bottom"
    round
    @close="closePop"
  >

    <van-picker
      ref="picker"
      title="请选择时间"
      :columns="data.columns"
      @change="onChange"
      @cancel="cancelOn"
      @confirm="onConfirm"
      v-model="data.selectedValues"
    >
      <template #columns-top>
        <div
          class="title"
          style="height: 3rem"
        >
          <span>年</span>
          <span>月</span>
          <span>日</span>
          <span>时</span>
          <span>分</span>
          <span>秒</span>
        </div>
      </template>
    </van-picker>
  </van-popup>
</template>
<script setup lang="ts">
import {
  reactive,
  watch,
  getCurrentInstance,
  defineProps,
  defineEmits,
  ref,
  Ref
} from "vue";

const values: Ref<string> = ref(""); //时间值 YYYY-MM-DD HH:mm:ss

const customFieldName = {
  text: "value",
  value: "values",
  children: ""
};
const data = reactive({
  isPicker: false, //是否显示弹出层
  columns: [], //所有时间列
  selectedValues: [] //控件选择的时间值
});

const props = defineProps({
  // 传入的值
  values: {
    type: String
  },
  // 单元格名称
  cellTitle: {
    type: String
  }
});

watch(
  () => props.values,
  val => {
    if (val) {
      values.value = props.values;
    } else {
      let dateVaules = new Date(); //默认当前时间
      values.value = formatDate(dateVaules);
    }
    data.columns = [];
    getcolumns();
  },
  {
    immediate: true //立即监听--进入就会执行一次 监听显影状态
  }
);

function onChange() {}

function showPopup() {
  data.isPicker = true;
}
/**
 * @description: 获取时间列
 */
function getcolumns() {
  let strtime = props.values; //传入的时间
  let date = new Date(strtime.replace(/-/g, "/"));
  let timeVaules = date.getTime();
  let dateVaules;
  if (props.values != "") {
    dateVaules = new Date(timeVaules);
  } else {
    dateVaules = new Date(); //默认当前时间
  }

  let Y = dateVaules.getFullYear();
  let M = dateVaules.getMonth();
  let D = dateVaules.getDate();
  let h = dateVaules.getHours();
  let m = dateVaules.getMinutes();
  let s = dateVaules.getSeconds();

  let year = []; //年
  year.values = [];
  let Currentday = new Date().getFullYear();
  for (let i = Currentday - 10; i < Currentday + 10; i++) {
    year.push({ text: i.toString(), value: i });
  }
  year.defaultIndex = year.values.indexOf(Y);

  // 补0
  const _M = M < 10 ? `0${M + 1}` : M.toString();
  const _D = D < 10 ? `0${D}` : D.toString();
  const _h = h < 10 ? `0${h}` : h.toString();
  const _m = m < 10 ? `0${m}` : m.toString();
  const _s = s < 10 ? `0${s}` : s.toString();

  // 生成年月日时分秒时间值
  data.selectedValues.push(Y);
  data.selectedValues.push(_M);
  data.selectedValues.push(_D);
  data.selectedValues.push(_h);
  data.selectedValues.push(_m);
  data.selectedValues.push(_s);

  data.columns.push(year);

  let month = []; //月
  month = Object.keys(Array.apply(null, { length: 13 })).map(function (item) {
    if (+item + 1 <= 10) {
      return { text: "0" + item, value: "0" + item };
    } else if (+item + 1 == 11) {
      return { text: +item, value: +item };
    } else {
      return {
        text: (+item + 0).toString(),
        value: (+item + 0).toString()
      };
    }
  });
  month.splice(0, 1);
  data.columns.push(month);

  //当月天数
  let days = getCountDays(Y, M + 1);
  let day = [];
  day = Object.keys(Array.apply(null, { length: days + 1 })).map(
    function (item) {
      if (+item + 1 <= 10) {
        return { text: "0" + item, value: "0" + item };
      } else if (+item + 1 == 11) {
        return { text: +item, value: +item };
      } else {
        return {
          text: (+item + 0).toString(),
          value: (+item + 0).toString()
        };
      }
    }
  );
  day.splice(0, 1);
  data.columns.push(day);

  let hour = []; //时
  hour = Object.keys(Array.apply(null, { length: 24 })).map(function (item) {
    if (+item + 1 <= 10) {
      return { text: "0" + item, value: "0" + item };
    } else if (+item + 1 == 11) {
      return { text: +item, value: +item };
    } else {
      return {
        text: (+item + 0).toString(),
        value: (+item + 0).toString()
      };
    }
  });
  data.columns.push(hour);

  let mi = []; //分
  mi = Object.keys(Array.apply(null, { length: 60 })).map(function (item) {
    if (+item + 1 <= 10) {
      return { text: "0" + item, value: "0" + item };
    } else if (+item + 1 == 11) {
      return { text: +item, value: +item };
    } else {
      return {
        text: (+item + 0).toString(),
        value: (+item + 0).toString()
      };
    }
  });
  data.columns.push(mi);

  let ss = []; //秒
  ss = Object.keys(Array.apply(null, { length: 60 })).map(function (item) {
    if (+item + 1 <= 10) {
      return { text: "0" + item, value: "0" + item };
    } else if (+item + 1 == 11) {
      return { text: +item, value: +item };
    } else {
      return {
        text: (+item + 0).toString(),
        value: (+item + 0).toString()
      };
    }
  });
  data.columns.push(ss);
}

/**
 * @description: 时间转换 格式:yyyy-MM-dd HH:mm:ss
 * @param: dateStr 格式:标准时间 new Date()
 */
function formatDate(dateStr) {
  const date = new Date(dateStr);
  const month = String(date.getMonth() + 1).padStart(2, "0");
  const day = String(date.getDate()).padStart(2, "0");
  const hours = String(date.getHours()).padStart(2, "0");
  const minutes = String(date.getMinutes()).padStart(2, "0");
  const seconds = String(date.getSeconds()).padStart(2, "0");
  const year = date.getFullYear();
  return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
}

/**
 * @description: 获取某年某月多少天
 * @param: year month
 */
function getCountDays(year, month) {
  let day = new Date(year, month, 0);
  return day.getDate();
}
/**
 * @description: 关闭底部弹窗
 * @param:
 */
function closePop() {
  data.isPicker = false;
}

//时间选择器关闭 值不改变并关闭弹框
function cancelOn({ selectedValues }) {
  data.isPicker = false;
}

// 时间选择器确定 值改变
function onConfirm({ selectedValues }) {
  let endval =
    selectedValues[0] +
    "-" +
    selectedValues[1] +
    "-" +
    selectedValues[2] +
    " " +
    selectedValues[3] +
    ":" +
    selectedValues[4] +
    ":" +
    selectedValues[5];
  values.value = endval;
  data.isPicker = false;
}
</script>

<style scoped lang="less">
.title {
  min-height: 4rem;
  padding: 2rem 0;
  display: flex;
  justify-content: space-around;
  align-items: center;
  color: #323233;
  font-weight: 800;
}
</style>

然后我踩了一个坑是,picker上面那个年月日时分秒的导航死活出不来,最后看了官方文档,他有固定的插槽名称就是这个:引用组件库是vant4的

然后这个还有个问题,希望路过的大佬可以指导,这块的距离实在不好看,我deep改了vant-cell的样式为什么死活不生效啊。这边就空的太开,让value怎么去靠右边一点,看起来好看一点。

  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值