ItemList组件实现
ItemSummary组件
收支明细的界面已经搭建好了,可以预料到的是,无论是本月还是今年上个月,list都会是相同的布局,只是展示的内容不一样罢了,所以我们对这一部分进行抽离。抽离成ItemSummary组件。
如图所示,时间分为本月、上月、今年、自定义时间四个维度。在使用ItemSummary的时候,直接用startDate等于一个时间是从0点0分开始,而我们需要endDate是从这一天的23点59分59秒开始计算。两者的逻辑是不一样的,需要进行if判断。如果是开始时间就从0点开始,结束时间就从23点59分59秒开始。
回到ItemSummary中,接受一个props里面有startDate和endDate。
我们没有使用day.js,但是之前封装了一个time.tsx时间库,进行一个API设计。
import { Time } from 'shared/time';
const time = new Time();
time.format('YYYY-MM-DD');
time.firstDayOfMonth(); //本月第一天
time.firstDayOfYear(); //今年第一天
time.lastDayOfMonth(); //本月最后一天
time.lastDayOfYear(); //今年最后一天
time.add(1, 'month'); //下个月
重构time
由于之前的time函数在使用时会产生一个api对象,会有内存使用的问题,所以将其绑定在原型上。把原来的time函数改成time类
format这一堆以及后续的api就绑定在原型上了。
以本月的第一天为例,返回一个新的时间对象包括年月日小时分钟秒
firstDayOfMonth() {
return new Time(new Date(this.date.getFullYear(), this.date.getMonth(), 1, 0, 0, 0));
}
回到ItemList先初始化时间,
const time = new Time() //创建当前时间
const customTime = reactive({
start: new Time(),
end: new Time() //自定义时间
})
本月,上月,今年
const timeList = [
{
start: time.firstDayOfMonth(),
end: time.lastDayOfMonth()
},
{
start: time.add(-1, 'month').firstDayOfMonth(),
end: time.add(-1, 'month').lastDayOfMonth()
},
{
start: time.firstDayOfYear(),
end: time.lastDayOfYear()
}
]
自定义时间
需要一个弹出对话框来选择时间,这里我们引入vant的组件来实现。并且使用我们之前做过的overlay组件
通过watcheffect添加监听,来控制开关
大致样式完成。
Form组件
接受四个属性 label,modelValue,type,error
content是计算属性,
如果type是text那么content就是input
如果type是emojiselect那么content就是emojiselect组件
如果是undefined,那么就是直接展示插槽
时间弹窗
它的值就是modelValue即用户想传的值,点击input让控制时间弹窗的按钮为true,展示popup内含有datepicker,类型为date,确认时,会把这个值更新出去,同时关闭popup,取消仅仅关闭popup
至此基本样式和逻辑完成
每次点击自定义时间都弹出对话框
在第一次跳转到自定义时间tab时会弹出对话框,确定之后,如果想再次弹出对话框就需要切换到别的tab再切换回来。这样太过于麻烦。
Vue3 的官方文档中给了v-model和jsx的写法。
需要我们写一个emit事件,然后再用onUpdate:selected={()=>}这种方式来进行v-model的绑定。
回到Tabs,加入emit事件
这样vue就会自动将selected和更新事件绑定到一起。
这样设置之后主动点击自定义时间也会触发对话框了。