第一次用vue3的api和ts寫,還在摸索中,有地方寫的不規範的,可交流,共同進步html
arhebin.gitee.io/vue-calenda…vue
vue-next
的源碼,既能學新api還能學ts,一箭雙鵰呢;固然其餘優質代碼也能夠reative, ref, watcher, watchEffect...
,選擇太多了,給開發者的組合方式也就多了,如今最缺的應該是最佳實踐了。useComputedDay
和useReducerDate
,有點意思props
,也能夠是state
組件自身的狀態,(看你喜歡)這些值都是基於當前日期的,因此你們會想到能夠用一個computed
來關聯起來,反正我這麼想了,😄git
舉個例子🌰github
index
index - 3 >= 0
就往小格子裏填入index - 3 + 1
;直到(30 + 3 - 1) < index
時,😯;剩餘頭尾(30 + 3 - 1) < index
,填入index - (30 + 3 - 1)
31 - (3 - index - 1)
代碼以下api
<p class="item" v-for="(el, index) in maxDays" :key="index">
<span :class="['day', el.isActive ? 'isactive' : '']"
v-if="(index - state.currentMonthFirstDay) >= 0 && (state.currentMonthMaxDays + state.currentMonthFirstDay - 1) >= index">
{{index - state.currentMonthFirstDay + 1}}
</span>
<span class="day rest " v-else-if="(state.currentMonthMaxDays + state.currentMonthFirstDay - 1) < index">{{index - (state.currentMonthMaxDays + state.currentMonthFirstDay - 1)}}</span>
<span class="day rest" v-else>{{state.preMonthMaxDays - (state.currentMonthFirstDay - index - 1)}}</span>
</p>
複製代碼
個人思路是寫一個dispatch
,靠action
的type去控制,只要改變固然輸入日期就好了。由於依賴已經關聯了;(可能一開始會寫個最簡單一個方法,if-else
的判斷)數組
<template>
//html結構
</template>
<script>
step() {
const nowDay = new Date().toLocaleDateString().split('/').map(Number)
const dayStr = ref<number[]>(nowDay) //這邊寫成數組,以前是字符串,但寫字符串有個問題就是年月日改變一個就會觸發因此依賴;數組能夠單純改變一個
//接來利用computed
//造成依賴
const date = computed(() => new Date(str.value.join('/')))
//年
const currentYear = computed(() => date.value.getFullYear())
//剩餘的值例如currentMonthMaxDays,preMonthMaxDays,currentMonthFirstDay
...
//handleChange改變日期的方法
const handleChange = () => {
if () {
//上一年
}
else if() {
//上個月
} else if() {
//下個月
} else if () {
//下一年
}
}
}
</script>
複製代碼
當你寫完,你會感受🐸,好長啊。就我我的而言,不怎麼喜歡在組件的入口把代碼的篇幅搞得很長。bash
如今基於vue3.0,我的感受數據,方法也能抽離,除了️組件抽離(只是我我的的想法,能夠交流)函數
useComputedDay
export const useComputedDay = (str: Ref<number[]>) => {
//注入了依賴
const date = computed(() => new Date(str.value.join('/')))
//年
const currentYear = computed(() => date.value.getFullYear())
//月
const currentMonth = computed(() => date.value.getMonth() + 1)
//日
const currentDate = computed(() => date.value.getDate())
//星期
const currentDay = computed(() => date.value.getDay())
//當月最大天數
const currentMonthMaxDays = computed(() => getMonthMaxDays(currentYear.value, currentMonth.value))
//當月星期幾
const currentMonthFirstDay = computed(() => computedFirstDay(currentYear.value, currentMonth.value))
//上一個月最大天數
// const preMonthMaxDays = computed(() => new Date(currentYear.value, currentMonth.value - 1, 0).getDate())
const preMonthMaxDays = computed(() => getMonthMaxDays(currentYear.value, currentMonth.value - 1))
return {
date,
currentYear,
currentMonth,
currentDate,
currentDay,
currentMonthMaxDays,
preMonthMaxDays,
currentMonthFirstDay
}
}
複製代碼
怎麼用呢?佈局
const nowDay = new Date().toLocaleDateString().split('/').map(Number)
const dayStr = ref<number[]>(nowDay) //這邊寫成數組,以前是字符串,但寫字符串有個問題就是年月日改變一個就會觸發因此依賴;數組能夠單純改變一個
const dispatch = useReducerDate(dayStr)
const {
date,
currentYear,
currentMonth,
currentDate,
currentDay,
currentMonthMaxDays,
preMonthMaxDays,
currentMonthFirstDay
} = useComputedDay(dayStr);
複製代碼
這樣的話只要dayStr
改變了全部的都會改變學習
dispatch
,dispatch
怎麼寫呢?能夠抽離出來寫成相似reducer
那樣export const useReducerDate = (state: Ref<number[]>) => {
return function (action: action) {
switch(action.type) {
case 'preYear': {
const _var = state.value.map(Number)
_var[0] = _var[0] - 1;
state.value = _var
break;
}
case 'preMonth': {
cutMonth(state);
break;
}
case 'nextYear': {
const _var = state.value.map(Number)
_var[0] = _var[0] + 1;
state.value = _var
break;
}
case 'nextMonth': {
addMonth(state);
break;
}
default: {
state.value = new Date().toLocaleDateString().split('/').map(Number)
}
}
}
}
複製代碼
怎麼用呢?
<div class="textheader">
<i class="iconfont textItem" @click="dispatch({type: 'preYear'})"></i>
<i class="iconfont textItem" @click="dispatch({type: 'preMonth'})"></i>
<p class="textItem">
{{state.currentYear}} 年 {{state.currentMonth}} 月 {{state.currentDate}} 日
</p>
<i class="iconfont textItem " @click="dispatch({type: 'nextMonth'})"></i>
<i class="iconfont textItem" @click="dispatch({type: 'nextYear'})"></i>
</div>
const dispatch = useReducerDate(dayStr)
複製代碼
很簡單吧,香不香。
useReducerDate
還能在提取一下寫個相似 useReducer
,寫個可複用的函數export const useReducer = (state: Ref<any>, reducer: (state: Ref<any>, action: action) => any) => {
return function dispatch(val: action) {
reducer(state, val)
}
}
複製代碼