vue3编写时间轴

一、页面样式

二、代码实现

<!--
 * @Author: Varian LIn
 * @Date: 2022-04-01 15:04:15
 * @LastEditors: coco
 * @LastEditTime: 2022-04-06 17:33:28
 * @Description: 
-->
<template>
  <div class="date-pick">
    <div class="header">
      <p>时间跳转</p>
      <el-icon class="icon cp"><d-arrow-left /></el-icon>
    </div>
    <!-- 日历内容 -->
    <div class="content">
      <div class="content-top">
        <div class="content-top-arrows">
          <a href="javascript:;" id="option" @click="selectMonth"
            >{{ state.chinese[state.comp_time.split("/")[1] - 1] }}月</a
          >
          <div id="arrows" class="arrows-month">
            <a href="javscript:;" id="prev" @click="prevMonth"
              ><el-icon><caret-top /></el-icon
            ></a>
            <a href="javascript:;" id="next" @click="nextMonth"
              ><el-icon><caret-bottom /></el-icon
            ></a>
          </div>
        </div>
        <div class="content-top-arrows">
          <a href="javascript:;" id="option" @click="selectYear"
            >{{ state.comp_time.split("/")[0] }}年</a
          >
          <div id="arrows" class="arrows-year">
            <a href="javscript:;" id="prev" @click="prevYear"
              ><el-icon><caret-top /></el-icon
            ></a>
            <a href="javascript:;" id="next" @click="nextYear"
              ><el-icon><caret-bottom /></el-icon
            ></a>
          </div>
        </div>
      </div>
      <div class="caculater" v-show="state.showMonth && state.showYear">
      <div class="content-center">
        <ul class="content-center-weekday">
          <li v-for="(item, index) in state.weekday" :key="index">{{ item }}</li>
        </ul>
      </div>
      <div class="content-bottom">
        <ul
          class="content-bottom-row"
          v-for="(item, index) in state.dayAry"
          :key="index"
        >
          <li
            class="content-bottom-day"
            :class="{ gray: !el.cur, dayBorder: el.isSelect }"
            @click="getToday(el)"
            v-for="(el, index) in item"
            :key="index"
          >
            <span class="day-border"> {{ el.text }}</span>
          </li>
        </ul>
      </div>
      </div>
       <!--  月份或年份选择 -->
      <YearMonthPick  v-show="!state.showMonth ||!state.showYear"  :txt="123"/>
    </div>
    <!-- 日历内容 -->

    <div class="hour-pick">
      <div class="hour-pick-time">
        <a href="javascript:;" id="option">17时</a>
        <div id="arrows" class="arrows-hour">
          <a href="javscript:;" id="prev"
            ><el-icon><caret-top /></el-icon
          ></a>
          <a href="javascript:;" id="next"
            ><el-icon><caret-bottom /></el-icon
          ></a>
        </div>
      </div>
      <div class="hour-pick-icon">:</div>
      <div class="hour-pick-time">
        <a href="javascript:;" id="option">54分</a>
        <div id="arrows" class="arrows-minute">
          <a href="javscript:;" id="prev"
            ><el-icon><caret-top /></el-icon
          ></a>
          <a href="javascript:;" id="next"
            ><el-icon><caret-bottom /></el-icon
          ></a>
        </div>
      </div>
    </div>
    <div class="confirm">
      <el-button class="confirm-btn" type="primary" round>确定</el-button>
      <el-button class="confirm-btn" type="primary" round>取消</el-button>
    </div>
  </div>
</template>
<script setup>
import { reactive } from "@vue/reactivity";
import YearMonthPick from './YearMonthPick.vue';


//import { renderList, watch } from "@vue/runtime-core";
// let props =defineProps({valuemodel:String, });
const myDate = new Date();
const state = reactive({
  //六行
  dayAry: [],
  timeStr: "",
  weekday :["日", "一", "二", "三", "四", "五", "六"],
  chinese :[
  "一",
  "二",
  "三",
  "四",
  "五",
  "六",
  "七",
  "八",
  "九",
  "十",
  "十一",
  "十二",
],
  comp_time:
    myDate.getFullYear() +
    "/" +
    (myDate.getMonth() + 1) +
    "/" +
    myDate.getDate(), //props.valuemodel"2022/4/8"
  todayDate: myDate.getFullYear() +
    "/" +
    (myDate.getMonth() + 1) +
    "/" +
    myDate.getDate(),  
   todayMonth:(myDate.getMonth() + 1) ,
   todayYear: myDate.getFullYear(),
   showMonth:true,
   showYear:true,
});
state.dayAry = getRenderData(state.comp_time);
console.log("2222", myDate.getFullYear());

//value '年月日'
//获取当前的月份对应的天数和1号对应的日期"2022/4/8"
function getRenderData(value) {
  // debugger
  let dayAry = [];
  function getDayNum(str) {
    console.log(str, "str");
    let arr = str.split("/");
    let y = arr[0],
    m = arr[1];
    //返回每月的1号的日期
    return [new Date(y, m, 0).getDate(), new Date(y, m-1 , 1).getDay()];//
  }
  let [nums, first] = getDayNum(value);
  let n = 1;
  let nextMonthDay = 1;
  console.log(new Date('2022-4-1').getDay(),nums, first,dayAry );//30 5 
  function getLastMonthDays(str) {
    let arr = str.split("/");
    let y = arr[0],
      m = arr[1];
    //获取上个月的1号的日期
    let data = new Date(y, m - 1, 1);
    return new Date(data.getFullYear(), data.getMonth(), 0).getDate();
  }

  let preMonthDay = getLastMonthDays(value); //上一个月的最后一天
  console.log(preMonthDay);//31
  for (let i = 0; i < 6; i++) {
    let temp = [];
    for (var j = 0; j < 7; j++) {
      if (i == 0) {
        if (j < first) {
          temp.unshift({
            isSelect: false,
            cur: false,
            text: preMonthDay--,
            yearTime:state.comp_time,
          });
        } else {
          let obj = {
            isSelect: false,
            cur: true,
            text: n++,
            yearTime:state.comp_time,
          };
           if (obj.text == value.split("/")[2] && obj.yearTime == state.todayDate) {
            obj.isSelect = true;
          }
          temp.push(obj);
        }
      } else {
        let t = n++;
        if (t > nums) {
          temp.push({
            isSelect: false,
            cur: false,
            text: nextMonthDay++,
            yearTime:state.comp_time,
          });
        } else {
          let obj = {
            isSelect: false,
            cur: true,
            text: t,
            yearTime:state.comp_time,
          };
           if (obj.text == value.split("/")[2] && obj.yearTime == state.todayDate) {
            obj.isSelect = true;
          }
          temp.push(obj);
        }
      }
    }
    dayAry.push(temp);
  }
  return dayAry;
}

const prevYear = () => {
  let arr = state.comp_time.split("/");
  arr[0]--;
 
  state.comp_time = arr.join("/");
  state.dayAry = getRenderData(state.comp_time);
};
const nextYear = () => {
  let arr = state.comp_time.split("/");
  arr[0]++;
  
  state.comp_time = arr.join("/");
  state.dayAry = getRenderData(state.comp_time);
};
const prevMonth = () => {
  let arr = state.comp_time.split("/");
  let m = arr[1] / 1;
  if (m - 1 <= 0) {
    arr[1] = 12;
    arr[0]--;
  } else {
    arr[1]--;
  }
  
  state.comp_time = arr.join("/");
  state.dayAry = getRenderData(state.comp_time);
};
const nextMonth = () => {
  let arr = state.comp_time.split("/");
  let m = arr[1] / 1;
  if (m + 1 > 12) {
    arr[1] = 1;
    arr[0]++;
  } else {
    arr[1]++;
  }
 
  state.comp_time = arr.join("/");
  state.dayAry = getRenderData(state.comp_time);
};

const getToday = (el) => {
  if (el.cur) {
    let ary = state.comp_time.split("/");
    ary[2] = el.text;
  }
};

const selectMonth =()=>{
     state.showMonth=!state.showMonth

}
const selectYear =()=>{
      state.showYear=!state.showYear
}

/*watch(
()=>state.comp_time,
(str)=>{
    renderTitle(str);
}
);

 function renderTitle(str){
    let ary=str.split('/');
    state.timeStr=ary[0]+"年"+ary[1]+"月"+ary[2]+"日";
    state.dayAry=getRenderData(str);
}
renderTitle('2022/4/8'); */

//  state.dayAry=getRenderData(props.valuemodel);
/* export default {
  name: "",
}; */

/*

const emit =defineEmit([ "update:valuemodel","change"]);
const fn=()=>{
    emit("change",1,2)
} */
</script>
<style lang="scss" scoped>
.date-pick {
  width: 520px;
  max-height: 550px;
  min-height: 450px;
  border-radius: 10px 10px 2px 2px;
  background: rgba(11, 33, 66, 0.8);
  margin-bottom: 2px;
  position: absolute;
  left: 0;
  bottom: 140px;
}
.header {
  margin: 0 10px;
  display: flex;
  justify-content: space-between;
  align-items: center;
  position: relative;
  p {
    margin: 12px 10px;
    color: rgba(201, 213, 226, 1);
  }
  .icon {
    transform: rotate(-90deg);
    margin-right: 10px;
  }
  &::after {
    content: "";
    position: absolute;
    left: 0;
    bottom: 0;
    width: 100%;
    height: 1px;
    background: rgba(11, 63, 116, 1);
    // background: #fff;
  }
}

///添加代码
.content {
  margin: 20px 45px;
  //display: flex;
  position: relative;
  &::after {
    content: "";
    position: absolute;
    bottom: 0;
    left: 0;
    width: 426px;
    height: 1px;
    background: #546680;
  }
  .content-top {
    //position: absolute;
    top: 0;
    margin-bottom: 10px;
    width: 426px;
    display: flex;
    justify-content: space-between;
    align-items: center;
    font-size: 18px;
    font-family: Microsoft YaHei;
    font-weight: bold;
    color: #c9d5e2;
  }
  .content-center{
     margin: 20px 0px;
  .content-center-weekday {
    //position: absolute;
    display: flex;
    width: 426px;
    justify-content: space-between;
    align-items: center;
    font-size: 16px;
    font-family: Microsoft YaHei;
    font-weight: bold;
    color: #556c84;
    cursor: default;
  }
  }
  .content-bottom {
   // margin: 80px 0px 0px 0px;
    font-size: 18px;
    font-family: Microsoft YaHei;
    font-weight: 400;

    .content-bottom-row {
      display: flex;
      width: 426px;
      justify-content: space-between;
      align-items: center;
      .content-bottom-day {
        cursor: pointer;
        display: flex;
        justify-content: center;
        align-items: center;
        margin: 3px 0  10px 0;
        color: #a6b7c9;
        border-radius: 50%;
        border: solid 1px transparent;
        width: 28px;
        height: 28px;
      }
      .content-bottom-day:hover {
        border: 1px solid #3193ff;
      }
      .gray {
        color: #a6b7c970;
      }
      .dayBorder {
        background: #3193ff;
      }
    }
  }
}

//时分
.hour-pick {
  margin: 0 75px;
  display: flex;
  justify-content: space-between;
  align-items: center;
  position: relative;
  font-size: 24px;
  font-family: Microsoft YaHei;
  font-weight: bold;
  color: #c9d5e2;
  cursor: default;
  .hour-pick-time {
    width: 146px;
    height: 55px;
    background: #021c35;
    box-shadow: 0px 4px 6px 0px rgba(11, 33, 66, 0.14);
    border-radius: 10px;
    justify-content: center;
    align-items: center;
  }
}
//确认按钮
.confirm {
  margin: 15px 45px;
  display: flex;
  position: relative;
  justify-content: end;
  align-items: center;
  .confirm-btn {
    width: 100px;
    height: 36px;
  }
}

// 时间按键位置颜色变化
.content-top-arrows,
.hour-pick-time {
  display: flex;
  #arrows {
    margin-left: 10px;
    
    #next {
      margin-top: -15px;
      display: flex;
    }
  }
}
a:hover {
  color: #3193ff !important;
}
</style>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值