手把手撸一个小而美的日历组件
前言
日历是前端开发中常见的业务组件之一,虽然现在有很多现成的日历组件,但是呢很多时候需要定制的时候就需要我们自己造一个,此时我们便需要了解日历的生成原理。其实也没有想象中的那么复杂。
今天我给大家带来手把手带你撸一个日历组件的教程,本教程使用Vue开发一个小而美的日历,主要讲解实现日历的基本思路,觉得有用的小伙伴记得三连一波啊。
环境准备
使用vue脚手架搭建的vue2.0项目,css预处理器选择scss即可
上手开撕
1.构思日历原型
画出日历草图,构建出日历常见的骨架。当然啦,也可以借鉴一些已有的日历的外观,这里我采用较为常见的外观,包含基本的日期展示,切换月份和年份,以及显示当前月份的功能。
首先我们新建一个组件,随便起个名,写好基本结构,这里不讲样式,所以先把所有的样式代码放上:
<template>
<div class="calendar">
<div class="header"></div>
<div class="body"></div>
</div>
</template>
<script>
export default {
name: "DemoCalendar",
};
</script>
<style lang="scss" scoped>
$primary-color: #3464e0;
.calendar {
background-color: #fff;
}
.header {
padding: 0 12px;
display: flex;
justify-content: center;
border-bottom: 1px solid #eee;
.current-date {
text-align: center;
font-size: 17px;
padding: 16px 8px;
color: #030303;
}
.btn-group {
display: flex;
align-items: center;
justify-content: center;
.btn {
display: flex;
align-items: center;
justify-content: center;
background: #fff;
color: #606266;
text-align: center;
box-sizing: border-box;
font-weight: 500;
width: 34px;
height: 26px;
font-size: 18px;
}
}
}
.body {
border-bottom: 1px solid #eee;
.weeks {
display: flex;
font-size: 15px;
padding: 16px 0;
.week-item {
flex: 1;
text-align: center;
font-weight: bold;
}
}
.day-list {
display: flex;
flex-wrap: wrap;
.day-item {
display: flex;
justify-content: center;
align-items: center;
width: 14.285%;
height: 40px;
text-align: center;
padding: 12px 0;
font-size: 18px;
color: #c8c8c8;
&.current-month-day {
display: flex;
align-items: center;
justify-content: center;
color: #171717;
font-weight: bold;
}
&.active {
.text {
display: flex;
align-items: center;
justify-content: center;
width: 40px;
height: 40px;
border-radius: 100%;
box-sizing: border-box;
background-color: #ddd;
padding: 14px 0;
}
}
&.active {
.text {
position: relative;
}
}
}
}
}
</style>
页面整体可分为两大部分,我起类名为header和body
header部分代码:
<div class="header">
<div class="btn-group">
<div class="btn btn-prev">
<span>«</span>
</div>
<div class="btn btn-prev">
<span>‹</span>
</div>
<div class="current-date">10月24日</div>
<div class="btn btn-next">
<span>›</span>
</div>
<div class="btn btn-next">
<span>»</span>
</div>
</div>
</div>
body的话又可以分为星期标题和日期列表,这两部分都采用循环比较合适,当然了,由于标题是不变的,也可以直接写死。
<!--写死-->
<div class="weeks">
<div class="week-item">日</div>
<div class="week-item">一</div>
<div class="week-item">二</div>
<div class="week-item">三</div>
<div class="week-item">四</div>
<div class="week-item">五</div>
<div class="week-item">六</div>
</div>
<!--循环-->
<div class="weeks">
<div class="week-item" v-for="week in weeks" :key="week">
{
{ week }}
</div>
</div>
接下来就是设计日期列表了,我们依旧先写死即可
<div class="day-list">
<div class="day-item" v-for="i of 35" :key="i">
<span class="text">{
{ i }}</span>
</div>
</div>
好了,到这里我们实现了一个这样的日历
此时我们的日期颜色的暗色的,为了凸显当前显示的月份的颜色,我们可以添加个类名,例如current-month-day,效果如下所示:
<div class="day-list">
<div class="day-item current-month-day" v-for="i of 35" :key="i">
<span class="text">{
{ i }}</span>
</div>
</div>
为了动态控制这个状态,我们每个日期最好设计成一个对象,这样可以存储更多的信息:
{
type: "current-month-day", // 日期类型,取值为[pre|current|next]-month-day,表示[上|今|下]月的日期
day: 1 // 日期数字
}
因此,我们改造这个循环:
<div class="day-list">
<div
class="day-item"
:class="[day.type]"
v-for