封装vuetify3中v-time-picker组件,并解决使用时分秒类型只能在修改秒之后v-model才会同步更新的问题

目前时间组件还属于实验室组件,要使用需要单独引入,具体使用方式查看官网

创建公共时间选择器组件

common-time-pickers.vue 子组件页面

复制代码
<template>
  <div>
    <v-dialog v-model="props.timeItem.isShow" activator="parent" width="auto">
      <v-time-picker
        v-if="props.timeItem.isShow"
        v-model="timeVal"
        use-seconds
        format="24hr"
        color="primary"
        class="pa-0"
        @update:hour="updateHour"
        @update:minute="updateMinute"
        @update:second="updateSecond"
      >
        <template v-slot:title>
          <!-- title null -->
        </template>
        <template v-slot:actions>
          <div class="mt-6">
            <v-btn @click="emit('close')">取消</v-btn>
            <v-btn color="primary" @click="saveTime">确认</v-btn>
          </div>
        </template>
      </v-time-picker>
    </v-dialog>
  </div>
</template>

<script setup>
const props = defineProps({
  timeItem: {
    type: Object,
    default: () => {
      return {
        isShow: false,
        time: "00:00:00",
        index: 0, //操作索引,可不传
        type: "", //操作类型
      };
    },
  },
});

const emit = defineEmits(["update:timeItem", "close"]);

const timeVal = ref(props.timeItem.time);

const hours = ref(0);
const minutes = ref(0);
const seconds = ref(0);

watch(
  toRef(props, "timeItem"),
  (newVal) => {
    if (newVal.isShow) {
      timeVal.value = newVal.time;
      // const [h, m, s] = newVal.time.split(':');
      // hours.value = parseInt(h, 10);
      // minutes.value = parseInt(m, 10);
      // seconds.value = parseInt(s, 10);
      // updateTimeVal();
    }
  },
  { deep: true }
);

// 因为组件中使用了use-second,默认只有在"秒"发生改变时,v-model中的值才会更新,
// 所以需要额外绑定"时"、"分"、"秒" 的事件进行处理
const updateHour = (val) => {
  hours.value = val;
  updateTimeVal("hour");
};

const updateMinute = (val) => {
  minutes.value = val;
  updateTimeVal("minute");
};

const updateSecond = (val) => {
  seconds.value = val;
  updateTimeVal("second");
};

const updateTimeVal = (updatedPart) => {
  let [currentHours, currentMinutes, currentSeconds] = timeVal.value.split(":");

  // 确保每次更新时不改变其他值,否则修改"时"或其他值时,可能会导致"分"和"秒"被联动更改
  if (updatedPart === "hour") {
    currentHours = padZero(hours.value);
  } else if (updatedPart === "minute") {
    currentMinutes = padZero(minutes.value);
  } else if (updatedPart === "second") {
    currentSeconds = padZero(seconds.value);
  }

  timeVal.value = `${currentHours}:${currentMinutes}:${currentSeconds}`;
  // console.log("更新了++++", timeVal.value);
};

const padZero = (num) => {
  return num < 10 ? "0" + num : num.toString();
};

const saveTime = () => {
  emit("close");
  emit("update:timeItem", {
    time: timeVal.value,
    index: props.timeItem.index,
    type: props.timeItem.type,
  });
};
</script>

<style lang="scss" scoped></style>

页面效果

我这里修改的是表格中的开始时间和结束时间,属于数组中值需要遍历,如果你只需要设置单个值,可不传索引

父组件中使用

vue中

复制代码
<template>
  <div>
  <!--输入框调用子组件,可以有多个输入框,这里只演示一个,item.endTime是输入框同步的时间,也会更新到子组件中,index是操作的对象索引,如果不传递需要对selecteTime方法稍作修改,endTime是修改的对象键值,方便拿到返回值时更新父组件的值-->
  <v-text-field
        v-model="item.endTime"
        readonly
         hide-details
         density="compact"
         @click="selecteTime(item.endTime, index, 'endTime')"
      >
   </v-text-field>
   
     <!--引入组件-->
    <common-time-pickers
      :timeItem="timeItem"
      @close="timeItem.isShow = false"
      @update:timeItem="updateTimeItem"
    />
     </div>
</template>

script中

复制代码
 import commonTimePickers from "@/components/common-time-pickers.vue"
 
<script setup>
const timeItem = ref({});

// 输入框触发,选择时间
const selecteTime = (time, index, type) => {
  timeItem.value = {
    isShow: true,//打开弹框
    time,//时间,需要同步更新到子组件中
    index,//修改的对象索引(非必须)
    type,//修改的对象字段类型
  };
};

//确认更新时间
const updateTimeItem = (payload) => {
  timeItem.value.isShow = false;
  const { time, index, type } = payload;
  // console.log("确定时间>>>", payload);
  // 使用展开运算符和计算属性名更新对象
  // 更新desserts数组中索引为index的type字段值(已经可以收到时间子组件传递过来的最新的值了,根据自己的需求更改父组件中值)
  desserts.value[index] = { ...desserts.value[index], [type]: time };
};


</script>
相关推荐
子兮曰1 天前
jev-ultrafast 深度解析:7 秒订机票的浏览器 Agent 是如何炼成的
前端·后端·agent
子兮曰1 天前
Jev 爆发一周:7 秒 Agent 背后的 System One 生态与三场争议
前端·后端·ai编程
前端小万1 天前
写公众号赚了 3000 块后,我做了一款叫 "一键成稿" 的软件
前端·微信小程序
爱勇宝1 天前
ZCode 开源 24 小时:一份没有历史的账本,回答不了"有没有偷代码"
前端·后端·chatglm (智谱)
三十而立洋1 天前
Cookie 详解:从产生到安全,一次讲透
前端·javascript
卡布鲁1 天前
把一个 Vite + Vue3 应用塞进 qiankun (React + Umi3) 主站:十个坑的复盘
前端·javascript·react.js
李少兄1 天前
JavaScript 隐式全局变量解析
javascript
汉堡大王95271 天前
Jev:不是聊天机器人, 而是一个智能 if 语句
前端·人工智能·后端
梦想很大很大1 天前
从运行事实到回归证据:Workrun 的 Telemetry 与 Evaluation 实践
前端·人工智能·后端
计算机魔术师1 天前
Meta Muse agent 接入 Shopify 的 Shop Pay 实现代理式购物
前端