第一次用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)
}
}
复制代码