欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Vue3時(shí)間軸組件問(wèn)題記錄(時(shí)間信息收集組件)

 更新時(shí)間:2024年09月10日 14:29:07   作者:博客風(fēng)氣調(diào)查員  
本文介紹了如何在Vue3項(xiàng)目中封裝一個(gè)時(shí)間信息收集組件,采用雙向綁定響應(yīng)式數(shù)據(jù),通過(guò)對(duì)Element-Plus的Slider組件二次封裝,實(shí)現(xiàn)時(shí)間軸功能,解決了小數(shù)計(jì)算導(dǎo)致匹配問(wèn)題和v-model綁定組件無(wú)效問(wèn)題,感興趣的朋友跟隨小編一起看看吧

背景

最近公司要求新增一個(gè)大屏頁(yè)面,需要封裝一個(gè)時(shí)間信息收集組件。通過(guò)雙向綁定響應(yīng)式數(shù)據(jù),父組件監(jiān)聽(tīng)子組件對(duì)數(shù)據(jù)的操作。最終將信息作為接口參數(shù),請(qǐng)求相應(yīng)的數(shù)據(jù),渲染至頁(yè)面上。

技術(shù)棧

Vue3(3.2.45)

Element-Plus(2.2.27)

dayjs(^1.11.7)

效果

其中時(shí)間軸是對(duì)Element Plus組件庫(kù)中的Slider滑塊組件的二次封裝,使用樣式穿透自定義樣式,同時(shí)大家可以把onMounted生命周期中的代碼取消注釋,可以做更多的操作。我的另一篇文章也是時(shí)間軸組件的封裝,不過(guò)兩者略有區(qū)別,所以又單獨(dú)記錄一下。

代碼

父組件關(guān)鍵代碼

<!-- 時(shí)間選擇 表單 -->
<h1 class="titleH2">     
    {{ titleTime[0] }} - {{ titleTime[1] }} <br />       
</h1>
<div class="contentCenter_bottom">
    <TimeForm v-model:up="objInfo" v-model:tt="titleTime"></TimeForm>
</div>
<script setup>
// 雙向綁定 obj
let objInfo = ref(null);
// 雙向綁定 標(biāo)題時(shí)間
let titleTime = ref(null);
// 監(jiān)聽(tīng)時(shí)間表單變化 - 針對(duì)左右兩側(cè)的數(shù)據(jù)
watch(objInfo, (newVal) => {
  console.log(newVal, "父組件監(jiān)聽(tīng)到變化");
});
</script>

時(shí)間收集組件代碼

關(guān)鍵變量介紹

這些變量實(shí)際可以對(duì)外暴露出去,也就是讓父組件去定義,讓組件更具靈活性。

  • optionsHour :每日小時(shí)節(jié)點(diǎn)配置項(xiàng)(可自行靈活配置)
  • optionsDay :每周天數(shù)配置項(xiàng)(可自行靈活配置)
  • LastDay :時(shí)間軸根據(jù)當(dāng)前時(shí)間該變量往前推多少天,之后for循環(huán)會(huì)利用該變量為marks賦值,并求出步進(jìn)值stepValue 。

<template>
  <div id="TimeForm">
    <div class="top">
      <div class="topContent">
        <div class="topContent_left">
          <el-button
            v-for="(item, index) in optionsHour"
            :key="index"
            size="small"
            :type="indHour == index ? 'primary' : ''"
            style="
              font-family: 'DIGIB';
              font-size: 15px;
              border-radius: 6px 6px 0px 0px;
            "
            @click="handleHour(index)"
            >{{ item }}</el-button
          >
        </div>
        <el-divider direction="vertical" style="height: 80%" />
        <div class="topContent_right">
          <el-button
            v-for="(item, index) in optionsDay"
            :key="index"
            size="small"
            :type="indDay == index ? 'primary' : ''"
            style="
              font-family: 'DIGIB';
              letter-spacing: 1px;
              font-size: 15px;
              border-radius: 6px 6px 0px 0px;
              padding-left: 7px;
              padding-right: 7px;
            "
            @click="handleDay(index)"
            >{{ item }}</el-button
          >
        </div>
      </div>
    </div>
    <div class="bottom">
      <el-slider
        v-model="value"
        :marks="marks"
        :step="stepValue"
        :show-tooltip="true"
        :format-tooltip="handleFormatTooltip"
      />
    </div>
  </div>
</template>
<script setup>
// vue
import {
  ref,
  reactive,
  watch,
  watchEffect,
  computed,
  onBeforeMount,
  onMounted,
  onBeforeUpdate,
  onUpdated,
  onBeforeUnmount,
  onUnmounted,
  defineProps,
  defineEmits,
} from "vue";
// 時(shí)間處理
import dayjs from "dayjs";
// 宏
let props = defineProps(["up", "tt"]);
const emits = defineEmits(["update:up", "update:tt"]);
// 定義變量
let optionsHour = reactive(["2點(diǎn)", "8點(diǎn)", "14點(diǎn)", "20點(diǎn)"]);
let optionsDay = reactive([
  "過(guò)去1天",
  "過(guò)去2天",
  "過(guò)去3天",
  "過(guò)去4天",
  "過(guò)去5天",
  "過(guò)去6天",
  "過(guò)去7天",
]);
// 高亮
let indHour = ref(0);
let indDay = ref(0);
// 步長(zhǎng)
let stepValue = ref(0);
// slider 日期往前推多少天
let LastDay = ref(7);
// 當(dāng)前時(shí)間
let NowTime = new Date().getTime();
// slider 值
const value = ref(0);
// 標(biāo)記
const marks = reactive({});
// 方法
function GetOneWeek() {
  // 為marks賦值
  for (let i = LastDay.value, j = 0; i >= 0; i--, j++) {
    let time = new Date(NowTime - i * 24 * 60 * 60 * 1000).getTime();
    let t = dayjs(time).format("YYYY-MM-DD");
    let num = Number(((100 * j) / LastDay.value).toFixed(1));
    // console.log(num);
    marks[num] = `${t}`;
    // console.log(i, j, "ij");
  }
  // 步進(jìn)值
  stepValue.value = 100 / LastDay.value;
}
GetOneWeek();
// 函數(shù)
// 高亮
function handleHour(val) {
  indHour.value = val;
}
function handleDay(val) {
  indDay.value = val;
}
// 自定義 提示信息
function handleFormatTooltip(val) {
  let num = Number(val.toFixed(1));
  return marks[num];
}
// 監(jiān)聽(tīng)
// watch([indHour, indDay, value],([newHour,newDay,newValue],[oldHour,oldDay,oldValue])=>{
//     console.log(newHour,newDay,newValue);
//     emits("update:objInfo", !props.objInfo);
// })
watchEffect(() => {
  let hour, endTime, hourMinuteSecond;
  let num = Number(value.value.toFixed(1));
  switch (indHour.value) {
    case 0:
      hourMinuteSecond = 2;
      break;
    case 1:
      hourMinuteSecond = 8;
      break;
    case 2:
      hourMinuteSecond = 14;
      break;
    case 3:
      hourMinuteSecond = 20;
      break;
  }
  switch (indDay.value) {
    case 0:
      hour = (indDay.value + 1) * 24;
      break;
    case 1:
      hour = (indDay.value + 1) * 24;
      break;
    case 2:
      hour = (indDay.value + 1) * 24;
      break;
    case 3:
      hour = (indDay.value + 1) * 24;
      break;
    case 4:
      hour = (indDay.value + 1) * 24;
      break;
    case 5:
      hour = (indDay.value + 1) * 24;
      break;
    case 6:
      hour = (indDay.value + 1) * 24;
      break;
  }
  // console.log(marks,value.value);
  endTime = marks[num];
  let obj = {
    hour: hour,
    hourMinuteSecond: hourMinuteSecond,
    endTime: endTime,
  };
  // console.log(marks[0],marks[100]);
  let timeStart = marks[0].replace(/-/, '年').replace(/-/, '月') + '日';
  let timeEnd = marks[100].replace(/-/, '年').replace(/-/, '月') + '日';
  console.log(timeStart);
  let timeObj = [timeStart,timeEnd]
  emits("update:up", obj);
  emits("update:tt", timeObj);
});
// 生命周期
onBeforeMount(() => {});
onMounted(() => {
  // 無(wú)需刪除這段注釋 或許日后有用
  //   document.querySelector(".el-slider__bar").innerHTML = `
  //   <div
  //   style="width:50px; height:24px;background:#ccc; position: absolute;right: 0px;top: -34px;transform: translateX(50%); display: flex; justify-content: space-between;"
  //   >
  //     <span id='span1'>1</span><span id='span2'>2</span>
  //   </div>
  //   `;
  //   document.querySelector(".bottom").addEventListener("click", (e) => {
  //     if (e.target.id == "span1") {
  //       console.log("實(shí)況");
  //     } else if (e.target.id == "span2") {
  //       console.log("預(yù)報(bào)");
  //     }
  //   });
});
</script>
<style lang="scss" scoped>
// 變量
$timeform-height: 110px;
$top-height: 30px;
#TimeForm {
  width: 100%;
  min-height: $timeform-height;
  max-height: $timeform-height;
  box-sizing: border-box;
  //   border: 1px dashed rgba(255, 255, 255, 0.5);
  // background-color: white;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  align-items: center;
  user-select: none;
  .top {
    width: 100%;
    height: $top-height;
    padding: 0px 20px;
    .topContent {
      width: auto;
      height: 100%;
      border-radius: 3px 3px 0px 0px;
      backdrop-filter: blur(10px); /* 背景模糊效果 */
      background-color: rgba(255, 255, 255, 0.5);
      display: flex;
      justify-content: flex-start;
      align-items: end;
      padding: 0px 10px;
      .topContent_left {
        width: 260px;
        height: 80%;
        display: flex;
        justify-content: space-around;
        align-items: end;
      }
      .topContent_right {
        width: auto;
        height: 80%;
        display: flex;
        justify-content: space-around;
        align-items: end;
        flex-wrap: wrap;
      }
    }
  }
  .bottom {
    width: 100%;
    height: calc($timeform-height - $top-height);
    background-color: rgba(255, 255, 255, 0.95);
    backdrop-filter: blur(10px); /* 背景模糊效果 */
    display: flex;
    justify-content: center;
    align-items: center;
    padding: 0px 45px;
  }
  :deep(.bottom .el-slider__stop) {
    width: 2px;
    height: 14px;
    background-color: #005edc;
    border-radius: 0px;
  }
  :deep(.bottom .el-slider__bar) {
    background-color: transparent;
    // position: relative;
  }
  :deep(.bottom .el-slider__marks-text) {
    background-color: #e0eaf8;
    color: #626f80;
    padding-left: 2px;
    padding-right: 2px;
  }
  //   :deep(.bottom .el-slider__button-wrapper::before){
  //     position: absolute;
  //     right: 0px;
  //     top: -17px;
  //     transform: translateX(calc(50% - 18px));
  //     display: inline-block;
  //     content: '123';
  //     width: 60px;
  //     height: 20px;
  //     background: #005edc;
  //     z-index: 9999999;
  //   }
}
</style>

所遇問(wèn)題

1.由于marks(取值范圍在閉區(qū)間0-100)的賦值是根據(jù)LastDay 變量計(jì)算出來(lái)的,具體來(lái)說(shuō)是這段代碼:

Number(((100 * j) / LastDay.value).toFixed(1));(最初是沒(méi)有.toFixed(1))

這導(dǎo)致計(jì)算有可能存在很長(zhǎng)的小數(shù),由于小數(shù)的存在,又使得watchEffect當(dāng)中的

let num = Number(value.value.toFixed(1));endTime = marks[num];(最初沒(méi)有.toFixed(1))

有可能匹配不上返回 undefined。

也有嘗試使用Math中的四舍五入或向上/下取整解決,但這又導(dǎo)致滑塊對(duì)應(yīng)不上步進(jìn)值,最終采取了.toFixed(1)解決該問(wèn)題。(.toFixed()返回值是字符串)

2.代碼中的v-model綁定組件必須采用別名方式,否則無(wú)效。

到此這篇關(guān)于Vue3時(shí)間軸組件(時(shí)間信息收集組件)的文章就介紹到這了,更多相關(guān)Vue3時(shí)間軸組件內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Vue?中使用?WebWorker的示例代碼

    Vue?中使用?WebWorker的示例代碼

    這篇文章主要介紹了Vue中使用WebWorker的示例代碼,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-08-08
  • vue自定義開(kāi)關(guān)組件使用詳解

    vue自定義開(kāi)關(guān)組件使用詳解

    這篇文章主要為大家詳細(xì)介紹了vue自定義開(kāi)關(guān)組件的使用,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-02-02
  • Vue3中使用jsx/tsx的教程詳解

    Vue3中使用jsx/tsx的教程詳解

    這篇文章主要為大家詳細(xì)介紹了如何在Vue3中使用jsx/tsx的相關(guān)知識(shí),文中的示例代碼講解詳細(xì),具有一定的借鑒價(jià)值,需要的小伙伴可以了解下
    2024-02-02
  • 配置一個(gè)vue3.0項(xiàng)目的完整步驟

    配置一個(gè)vue3.0項(xiàng)目的完整步驟

    這篇文章主要介紹了配置一個(gè)vue3.0項(xiàng)目的完整步驟,從0開(kāi)始配置一個(gè)vue項(xiàng)目,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2019-04-04
  • Element Cascader 級(jí)聯(lián)選擇器的使用示例

    Element Cascader 級(jí)聯(lián)選擇器的使用示例

    這篇文章主要介紹了Element Cascader 級(jí)聯(lián)選擇器的使用示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-07-07
  • Vue制作Todo List網(wǎng)頁(yè)

    Vue制作Todo List網(wǎng)頁(yè)

    這篇文章主要為大家詳細(xì)介紹了Vue制作Todo List網(wǎng)頁(yè)的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-04-04
  • vue封裝一個(gè)簡(jiǎn)單的div框選時(shí)間的組件的方法

    vue封裝一個(gè)簡(jiǎn)單的div框選時(shí)間的組件的方法

    這篇文章主要介紹了vue封裝一個(gè)簡(jiǎn)單的div框選時(shí)間的組件的方法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2019-01-01
  • 封裝一個(gè)更易用的Dialog組件過(guò)程詳解

    封裝一個(gè)更易用的Dialog組件過(guò)程詳解

    這篇文章主要為大家介紹了封裝一個(gè)更易用的Dialog組件過(guò)程詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-05-05
  • 詳解如何使用vue實(shí)現(xiàn)頁(yè)面訪問(wèn)攔截

    詳解如何使用vue實(shí)現(xiàn)頁(yè)面訪問(wèn)攔截

    這篇文章主要為大家詳細(xì)介紹了如何使用vue實(shí)現(xiàn)頁(yè)面訪問(wèn)攔截功能,文中的示例代碼講解詳細(xì),具有一定的參考價(jià)值,需要的可以了解一下
    2023-08-08
  • vue實(shí)現(xiàn)界面滑動(dòng)效果

    vue實(shí)現(xiàn)界面滑動(dòng)效果

    這篇文章主要為大家詳細(xì)介紹了vue實(shí)現(xiàn)界面滑動(dòng)效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-07-07

最新評(píng)論