就是项目是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怎么去靠右边一点,看起来好看一点。