首页 前端知识 前端之vue 封装自定义日历

前端之vue 封装自定义日历

2024-06-16 09:06:59 前端知识 前端哥 55 669 我要收藏

关于自定义日历

工作需要,现有框架封装的日历无法满足需求,又找不到更好的插件的情况下,咋办??自己写个呗!

效果图和功能说明

先看看效果图

在这里插入图片描述

其实基本界面就这样了,和其他没啥区别。
但是既然要单独封装一个,那肯定有其他可扩展的地方,不然就没意义了

功能说明

1、基本日历功能
2、可以自定义标题头部
3、可自定义顶部时间以及月份切换部分
4、日历单元格样式可以自定义
5、星期一栏可以自定义
6、可以在日历里面插入数据:这一点是最重要的,也是必须要自己封装的重要因素

使用

封装为日历组件,直接引用即可。需要扩展其他功能,可以看组件里面的props哦,这是可以接收的参数。当然,如果用props不能满足的,那就看看里面的slot插槽部分咯。

这是props定义接收的参数,每个参数均有注释,这里不多做介绍。
 props: {
      initDate:{
        type:[String,Date,Number],
        default:()=>new Date()
      },//初始化日期
      width:{
        type:[String,Number],
        default:'100%'
      },//日历宽度
      height:{
        type:[String,Number],
        default:'100%'
      },//日历高度
      calendarClass:String,//日历自定义样式类
      titleClass:String,//年月标题自定义样式类
      titleH:{
        type:[String,Number],
        default:'35px'
      },//年月标题高度
      titleBk:{
        type:String,
        default:'#ffffff'
      },//年月标题颜色
      bodyBk:{
        type:String,
        default:'#ffffff'
      },//日历体背景
      bodyClass:String,//日历体自定义样式
      dateDefaultClass:String,//日期自定义默认类名
      dateActivDateClass:String,//日期自定义选中类名
      dateDisabledDateClass:String,//日期自定义不可见类名
      titleDateConnector:String,//标题日期连接符
      insertData:{
        type:Array,
        default:()=>[]
      },//自定义拼接数据
      weeks:{
        type:Array,
        default:()=>['日','一','二','三','四','五','六']
      },//周数据
      dateProp:{
        type:String,
        default:'date'
      },//自定义表示时间的字段
      calenCellClass:String,//日历单元格自定义样式
      firstRowCellClass:String,//日历第一行单元格自定义样式
      firstColumCellClass:String,//日历第一列单元格自定义样式
      cellBorder:Boolean,//是否有边框
      cellTitleHeight:{
        type:[Number,String],
        default:'40px'
      },//日历标题高度
      cellTitleColor:{
        type:String,
        default:'#333333'
      },//日历标题颜色
      range:{
        type:Array,
        default:()=>[]
      },//日期范围

    },
更多个性化功能请看slot部分

在这里插入图片描述

插槽使用示例:
不熟悉插槽的伙伴可以去vue官网补补:https://cn.vuejs.org/v2/guide/components-slots.html

 <calendar>
                    <template #calendarTitle>
                        <div class="rowStart calendarTitle">
                            <i class="el-icon-date yellow font20"></i>
                            <strong class="font16" style="margin-left:5px;">日历标题</strong>
                        </div>
                    </template>
                    <template #calendarTop="{currentYear,currentMonth,changeMonth}">
                        <div class="rowBtween canlendar-top-box">
                            <div class="rowStart year-back-box">
                                <strong class="font24">{{currentYear}}年{{currentMonth}}月</strong>
                                <span class="blue back-today font14" @click="changeMonth(new Date())">返回今天</span>
                            </div>
                            <div class="change-month-box  rowBtween">
                                <i class="el-icon-arrow-left el-icon blue" @click="changeMonth(0)"></i>
                                <span></span>
                                <i class="el-icon-arrow-right el-icon blue" @click="changeMonth(1)"></i>
                            </div>
                        </div>
                    </template>
                </calendar>

其他不多说了,最后上代码。由于组件代码放在一个页面写重了点,因此分成了几个文件
所有data里面的变量,props,还有函数均有说明。
先看canlendar.vue

<template>
  <div class="custom-calendar" :style="{width:calendarWidth,height:calendarHeight}" :class="calendarClass">
    <div class="calendar-topBox">
      <slot name="calendarTitle"></slot>
      <slot name="calendarTop" :currentYear="currentYear" :currentMonth="currentMonth+1" :changeMonth="changeMonth">
        <div class="calendar-title rowBtween" :style="{height:titleHeight,background:titleBk}" :class="titleClass">
          <strong class="left">{{currentYear}}{{titleDateConnector || '年'}}{{currentMonth+1}}{{titleDateConnector ? '' : '月'}}</strong>
          <div class="right rowBtween">
            <span @click="changeMonth(0)">&lt;</span>
            <span @click="changeMonth(1)">&gt;</span>
           </div>
        </div>
      </slot>
    </div>
    <div class="calendar-body" :style="{background:bodyBk}" :class="bodyClass">
      <div class="bodyTitleBox rowCenter">
        <slot name="weeks">
          <span class="body-title rowCenter" :ref="index ? '' : 'calenCellTitle'" :style="{height:cellTitleHeight,color:cellTitleColor}" v-for="(week,index) in weeks" :key="index">{{week}}</span>
        </slot>
      </div>
      <div class="calen-content rowCenter">
        <div class="calen-cell" :id="'calen'+index" :ref="index ? '' : 'calenCell'" :class="[calenCellClass,index<7 ? 'firstRowCellClass': '',index%7===0 ? 'firstColumCellClass' : '']"  :style="{...calenCellStyle,...cellBorderStyle(index)}" v-for="(day,index) in calendarList" :key="index" @click="choose(day)">
          <slot name="day" :day="day">
            <span class="dateSpan rowCenter" :class="day.dateClass">{{day.day}}</span>
          </slot>
          <slot name="haveDataTag" :hasData="day.hasData" :isThis="day.isThis">
            <div v-show="day.hasData && day.isThis"></div>
          </slot>
        </div>
      </div>
    </div>
  </div>
</template>
<script>
  import {isValidDate,isNumber} from "./validate"
  import {getStartTimeEndTimeInfoFun,insertDataToCalendar} from './util'
  export default {
    name: "Calendar",
    props: {
      initDate:{
        type:[String,Date,Number],
        default:()=>new Date()
      },//初始化日期
      width:{
        type:[String,Number],
        default:'100%'
      },//日历宽度
      height:{
        type:[String,Number],
        default:'100%'
      },//日历高度
      calendarClass:String,//日历自定义样式类
      titleClass:String,//年月标题自定义样式类
      titleH:{
        type:[String,Number],
        default:'35px'
      },//年月标题高度
      titleBk:{
        type:String,
        default:'#ffffff'
      },//年月标题颜色
      bodyBk:{
        type:String,
        default:'#ffffff'
      },//日历体背景
      bodyClass:String,//日历体自定义样式
      dateDefaultClass:String,//日期自定义默认类名
      dateActivDateClass:String,//日期自定义选中类名
      dateDisabledDateClass:String,//日期自定义不可见类名
      titleDateConnector:String,//标题日期连接符
      insertData:{
        type:Array,
        default:()=>[]
      },//自定义拼接数据
      weeks:{
        type:Array,
        default:()=>['日','一','二','三','四','五','六']
      },//周数据
      dateProp:{
        type:String,
        default:'date'
      },//自定义表示时间的字段
      calenCellClass:String,//日历单元格自定义样式
      firstRowCellClass:String,//日历第一行单元格自定义样式
      firstColumCellClass:String,//日历第一列单元格自定义样式
      cellBorder:Boolean,//是否有边框
      cellTitleHeight:{
        type:[Number,String],
        default:'40px'
      },//日历标题高度
      cellTitleColor:{
        type:String,
        default:'#333333'
      },//日历标题颜色
      range:{
        type:Array,
        default:()=>[]
      },//日期范围

    },
    data() {
      return {
        calendarList: [],//日历数据
        activeDay: {},//选中日期信息
        currentYear: '',//显示的年
        currentMonth: '',//显示的月
        chooseDate: '',//选择的日期
        calenCellHeight:0,//日历单元格高度
        calenBotyTitleCellStyle:{},//日历顶部单元格样式
        calenCellStyle:{},//日历单元格样式
        calendarWidth:'100%',//日历宽度
        calendarHeight:'100%',//日历高度
        titleHeight:'35px',//年月标题高度
        dateCellDefaultClass:'',//日历单元格默认类名
        dateCellActiClass:'',//日历单元格选中类名
        dateCellDisabledClass:'',//日历不可见单元格类名
        cellBorderStyle:(index)=>{return {}},//日历单元格边框样式
        bodyCellTitleHeight:'40px'
      }
    },
    async created(){
      console.log(this.calenCellClass)
      let {width,height,titleH,dateDefaultClass,dateActivDateClass,dateDisabledDateClass,cellTitleHeight}=this
      this.calendarWidth=(typeof width==='number' || isNumber(width)) ? (width+'px') : width
      this.calendarHeight=(typeof height==='number' || isNumber(height)) ? (height+'px') : height
      this.titleHeight=(typeof cellTitleHeight==='number' || isNumber(cellTitleHeight)) ? (cellTitleHeight+'px') : cellTitleHeight
      this.bodyCellTitleHeight=(typeof titleH==='number' || isNumber(titleH)) ? (titleH+'px') : titleH
      this.dateCellDefaultClass=dateDefaultClass || 'dateDefaultCss'
      this.dateCellActiClass=dateActivDateClass || 'dateActiveCss'
      this.dateCellDisabledClass=dateDisabledDateClass || 'disableDateCss'
      let {dateTime,isValid}=isValidDate(this.initDate)
      if(!isValid) return
      let year=dateTime.getFullYear()
      let month=dateTime.getMonth()
      let date=dateTime.getDate()
      await this.init(year,month,date)
      insertDataToCalendar(this.insertData,this.calendarList,this.dateProp)
    },
    methods: {
      //初始化日历
      async init(year, month, date,config={}) {
        this.currentYear = year
        this.currentMonth = month
        let daysInMonth = new Date(year, month+1,0).getDate()//得到当前月份的天数  28,29,30,31
        let firstDayInWeek = new Date(year, month,1).getDay()//获取当月的一号是星期几
        let lastDayInWeek = new Date(year,month,daysInMonth).getDay()//获取当月最后一天是星期几
        this.calendarList = await this.createcalendarList(year, month, date, firstDayInWeek, lastDayInWeek, daysInMonth,config)
        return this.calendarList
      },
      //创建日历
      createcalendarList(year, month, date, firstDayInWeek, lastDayInWeek, daysInMonth,config={}) {
        return new Promise((resolve)=>{
          let thisYear=new Date().getFullYear()
          let thisMonth=new Date().getMonth()
          if(thisYear===year && thisMonth===month){
            date=new Date().getDate()
          }
          let {isChangeMonth}=config
          let { calenStartDate,calenEndDate,calenStartYear,calenStartMonth,dateRangeCode}=getStartTimeEndTimeInfoFun(this.range[0],this.range[1])
          // console.log(calenStartDate,calenEndDate,dateRangeCode,calenStartMonth)
          if(!isChangeMonth && dateRangeCode){
            //日期范围有效
            this.currentYear = calenStartYear
            this.currentMonth = calenStartMonth
          }
          let calendarList = []
          //1号不在星期天,补全前面的日期信息
          // console.log(firstDayInWeek)
          if (firstDayInWeek !== 0) {
            let prevMonthLastDate=new Date(year,month,0).getDate()
            for (let j = firstDayInWeek-1; j >= 0; j--) {
              calendarList.push({
                dateClass: this.dateCellDisabledClass,
                year,
                month,
                day: prevMonthLastDate - j,
                week: new Date(year,month-1,prevMonthLastDate - j).getDay(),
                isThis: false
              })
            }
          }
          // 添加日期信息
          for (let i = 0; i < daysInMonth; i++) {
            let dateClass=''
            let isRange=true
            if(!dateRangeCode || isChangeMonth){
              //日期范围值无效,已月份为范围
              dateClass= (i + 1) === date ? this.dateCellActiClass : this.dateCellDefaultClass
            }else{
              //日期范围值有效
              if(((i + 1) === date) && (calenStartDate<=(i+1) && (i+1)<=calenEndDate)){
                dateClass=this.dateCellActiClass
              }else if(calenStartDate<=(i+1) && (i+1)<=calenEndDate){
                dateClass=this.dateCellDefaultClass
              }else{
                dateClass=this.dateCellDisabledClass
                isRange=false
              }
            }
            let day = {
                dateClass,
                year,
                month:month+1,
                day: i + 1,
                week:new Date(year,month,i + 1).getDay(),
                isThis: true,
                isRange
              }
            ;((i + 1) === date) && (this.activeDay = day)
            calendarList.push(day)
          }
          //如果当月的最后一天不是星期六,后面补全日期信息
          if (lastDayInWeek !== 6) {
            for (let i = 0; i < 6 - lastDayInWeek; i++) {
              calendarList.push({
                dateClass: this.dateCellDisabledClass,
                year,
                month: month + 2,
                day: i + 1,
                week: new Date(year,month+1,i + 1).getDay(),
                isThis: false
              })
            }
          }
          // 如果单元格有边框,执行边框函数
          if(this.cellBorder){
            this.cellBorderStyle=index=> {
              return {
                'border-right-style':'solid',
                'border-bottom-style':'solid',
                'border-width':'1px',
                'border-color':'#dddddd',
                'border-top-style':index<7 ? 'solid' : '',
                'border-left-style':index%7===0 ? 'solid' : '',
              }
            }
          }
          resolve(calendarList)
        })

      },
      //点击选择日期
      choose(day) {
        console.log(day)
        let {isRange,isThis}=day
        if (isThis && isRange) {
          //本月
          this.activeDay.dateClass = this.dateCellDefaultClass
          this.activeDay = day
          day.dateClass = this.dateCellActiClass
           let month=day.month <10 ? '0'+day.month : day.month
           let myDay=day.day <10 ? '0'+day.day : day.day
          this.chooseDate = day.year + '-' + month + '-' + myDay
          this.$emit('getChooseDate', this.chooseDate)
        }
      },
      // 月份改变
      async changeMonth(value) {
          let year=null
          let month=null
          let day=1
          if(value===1 || value===0){
              //翻页操作
              if(value){
                  //向上翻
                  if (this.currentMonth === 11) {
                      this.currentYear++
                      this.currentMonth = 0
                  } else {
                      this.currentMonth++
                  }
              }else{
                  // 向下翻
                  if (this.currentMonth === 0) {
                      this.currentYear--
                      this.currentMonth = 11
                  } else {
                      this.currentMonth--
                  }
              }
              year=this.currentYear
              month=this.currentMonth
          }else{
              //时间格式
              if(typeof value !=='number' && typeof value !=='string' && !(value instanceof Date)){
                  console.error(`${value} 时间格式错误 `)
                  return
              }
              if(typeof value ==='string'){
                  value=value.replace(/-/g,'/')
              }
              year=new Date(value).getFullYear()
              month=new Date(value).getMonth()
              day=new Date(value).getDate()
          }

        await this.init(year, month,day,{isChangeMonth:true})//等待日历先创建完成
        insertDataToCalendar(this.insertData,this.calendarList,this.dateProp)
        this.$emit('monthChange')
      },

    },
    watch:{
      //监听插入数据
      insertData:{
        deep:true,
        handler:function (value) {
          console.log(value)
          insertDataToCalendar(value,this.calendarList,this.dateProp)
        },
      },
      //监听日期范围变化
      range:{
        deep:true,
        handler:async function ([startTime,endTime]) {
          if(startTime && endTime){
            await this.init(this.currentYear, this.currentMonth,1,)//等待日历先创建完成
            insertDataToCalendar(this.insertData,this.calendarList,this.dateProp)
          }
        },
      }
    }
  }
</script>
<style lang="less" scoped>
  @import "./style";
  @import "./flex";
</style>

工具文件util.js

//获取开始日期结束日期最终信息
export function getStartTimeEndTimeInfoFun(startDate,endDate){
  let start=checkStartTimeEndTimeFun(startDate)
  let end=checkStartTimeEndTimeFun(endDate)
  let calenStartDateResult=start ? getNewDateFun(start) : false
  let calenStartYear=calenStartDateResult ? calenStartDateResult.calendarAddYear : ''
  let calenStartMonth=calenStartDateResult ? calenStartDateResult.calendarAddMonth : ''
  let calenStartDate=calenStartDateResult ? calenStartDateResult.calendarAddDate : ''
  let calenEndDateResult=end ? getNewDateFun(end) : false
  let calenEndYear=calenEndDateResult ? calenEndDateResult.calendarAddYear : ''
  let calenEndMonth=calenEndDateResult ? calenEndDateResult.calendarAddMonth : ''
  let calenEndDate=calenEndDateResult ? calenEndDateResult.calendarAddDate : ''
  if(calenStartYear!==calenEndYear || calenStartMonth!==calenEndMonth || !calenEndDate || !calenStartDate || (calenStartDate>calenEndDate)){
    (start || end) && console.error(`日期范围仅支持本月范围选择或日期格式错误${startDate}  ${endDate}`)
    return {dateRangeCode:0}
  }
  return{
    calenStartYear,
    calenStartMonth:calenStartMonth-1,
    calenStartDate,
    calenEndYear,
    calenEndMonth:calenEndMonth-1,
    calenEndDate,
    dateRangeCode:1
  }
}
//检查开始日期和结束日期
export function checkStartTimeEndTimeFun(date){
  if(typeof date!=='string' && (typeof date==='string' && !date) && typeof date!=='number' && !(date instanceof Date)){
    //非时间可能的数据格式,或者明确时间没有值,跳过
    return ''
  }
  if(typeof date==='number' && date.length<10){
    console.error(`日期${date}格式错误,请使用正确的时间戳格式,例如:1593669468000`)
    return ''
  }
  if(typeof date==='string' && date){
    //传递过来的时间格式时字符串,此处不可以用parseInt,因为parseInt会将类似2020-02-02解析为2020
    if(!/-/.test(date) && !/\//.test(date && !Number(date))){
      console.error(`日期${date}格式错误,请使用正确的字符串日期格式,例如:2020-06-06,或2020/06/06`)
      return ''
    }
    if(!/-/.test(date) && !/\//.test(date) && Number(date)){
      date=Number(date)
    }
  }
  return date
}
//将传入的时间生成新的值并返回
export function getNewDateFun(date){
  let calendarAddYear=null
  let calendarAddMonth=null
  let calendarAddDate=null
  if(typeof date==='string'){
    //字符串,可能时2020-03-04或2020/02/03或03-02或03/02
    let dateArr=/-/.test(date) ? date.split('-') : date.split('/')
    if(dateArr.length===3){
      //年月日
      calendarAddYear=parseInt(dateArr[0])
      calendarAddMonth=parseInt(dateArr[1])
      calendarAddDate=parseInt(dateArr[2])
    }else if(dateArr.length===2){
      //月日,年默认为今年
      calendarAddYear=new Date().getFullYear()
      calendarAddMonth=parseInt(dateArr[0])
      calendarAddDate=parseInt(dateArr[1])
    }else{
      //其他未知情况,报错
      console.error(`日期${date}格式错误,请使用正确的字符串日期格式,例如:2020-06-06,或2020/06/06`)
      return false
    }
  }else{
    //时间戳和时间对象
    if(typeof date==='number'){
      //时间戳转为时间对象
      date=new Date(date)
    }
    calendarAddYear=date.getFullYear()
    calendarAddMonth=date.getMonth()+1
    calendarAddDate=date.getDate()
  }
  return{
    calendarAddYear,
    calendarAddMonth,
    calendarAddDate
  }
}
//将数据插入日历
export function insertDataToCalendar(value,calendarList,dateProp){
  if(!value.length || !(value instanceof Array)){
    return
  }
  for(let i=0;i<value.length;i++){
    let date=value[i][dateProp]
    // console.log(date)
    if(typeof date!=='string' && (typeof date==='string' && !date) && typeof date!=='number' && !(date instanceof Date)){
      //非时间可能的数据格式,或者明确时间没有值,跳过
      continue
    }
    if(typeof date==='number' && date.length<10){
      console.error(`日期${date}格式错误,请使用正确的时间戳格式,例如:1593669468000`)
      continue
    }
    if(typeof date==='string' && date){
      //传递过来的时间格式时字符串,此处不可以用parseInt,因为parseInt会将类似2020-02-02解析为2020
      if(!/-/.test(date) && !/\//.test(date && !Number(date))){
        console.error(`日期${date}格式错误,请使用正确的字符串日期格式,例如:2020-06-06,或2020/06/06`)
        continue
      }
      if(!/-/.test(date) && !/\//.test(date) && Number(date)){
        date=Number(date)
      }
    }
    let caldarTimeResult=getNewDateFun(date)
    if(!caldarTimeResult) return
    let {calendarAddYear,calendarAddMonth,calendarAddDate}=caldarTimeResult
    value[i]={...value[i],calendarAddYear,calendarAddMonth,calendarAddDate}
  }
  for(let i=0;i<calendarList.length;i++){
    let filterCalendarList=value.filter(item=>item.calendarAddYear===calendarList[i].year)//先筛选出当前年的
    filterCalendarList=filterCalendarList.filter(item=>item.calendarAddMonth===calendarList[i].month)//再筛选出当前月的
    filterCalendarList=filterCalendarList.filter(item=>item.calendarAddDate===calendarList[i].day)//最后筛选出当前天的
    // console.log(filterCalendarList)
    if(!filterCalendarList.length){
      // 没有值,跳过
      continue
    }
    // 将传过来的数据插入原日历数据
    calendarList.splice(i,1,{...calendarList[i],...filterCalendarList[0],hasData:true})
  }
}

日期验证文件validate.js

/**
 * 判断日期格式是否正确,正确返回日期
 */
export function isValidDate(dateTime) {
    let yourDate=dateTime
    try {
        ;(typeof dateTime === 'string') && (dateTime=dateTime.replace(/-/g,'/'))
        dateTime=new Date(dateTime)
        if(dateTime instanceof Date && !isNaN(dateTime.getTime())){
            return {
                dateTime,
                isValid:true,
            }
        }else{
            console.error(`日期 ${yourDate} 格式错误`)
            return {
                isValid:false,
            }
        }
    }catch (err){
        console.error(err)
    }

}

/**
 * 判断是否为数字,整数或者小数
 */
export function isNumber(val) {
    let regPos = /^\d+(\.\d+)?$/ //非负浮点数
    let regNeg = /^(-(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*)))$/ //负浮点数
    return regPos.test(val) || regNeg.test(val)
}

最后是样式文件style.less和flex.less
style.less

html,body,ul,li,p,span,div{
  margin:0;
  padding:0;
  -webkit-box-sizing: border-box;
  -moz-box-sizing: border-box;
  box-sizing: border-box;
}
.dateDefaultCss{
  color: black;
  cursor: pointer
}
.dateActiveCss{
  color: white;
  cursor: pointer;
  background:#317ef2;
}
.disableDateCss{
  color: #bfbfbf;
  cursor: default
}
.custom-calendar {
  .calendar-title {
    padding:0 30px 0 10px;
    .left {
      font-size: 105%;
    }
    .right {
      width:70px;
      border:solid 1px #dddddd;
      padding:0 10px;
      span{
        font-size: 20px;
      }
      span:hover {
        cursor: pointer;
        color: #3a82fa;
      }
    }
    margin-bottom: 5px;
    color: #000;
  }
  .calendar-body {
    padding-bottom:10px;
    .bodyTitleBox{
      .body-title {
        width:14%;
      }
    }
    .calen-content{
      flex-wrap:wrap;
    }
    .calen-cell {
      color: #000;
      display: table-cell;
      text-align: center;
      vertical-align: middle;
      width:14%;
      margin-bottom: 5px;
      .dateSpan{
        padding: 3px;
        -webkit-border-radius: 50%;
        -moz-border-radius: 50%;
        border-radius: 50%;
        width:20px;
        height:20px;
        margin:0 auto;
      }
      div{
        width: 3px;
        height: 3px;
        border-radius: 50%;
        background: #3a82fa;
        margin: 0 auto;
      }
    }
  }
}

flex.less

/*
flex布局样式
 */
/* flex布局 */
.rowStart {
  display: flex;
  flex-direction: row;
  justify-content: flex-start;
  align-items: center;
}

.rowAround {
  display: flex;
  flex-direction: row;
  justify-content: space-around;
  align-items: center;
}

.rowBtween {
  display: flex;
  flex-direction: row;
  justify-content: space-between;
  align-items: center;
}

.rowCenter {
  display: flex;
  flex-direction: row;
  justify-content: center;
  align-items: center;
}

.rowEnd {
  display: flex;
  flex-direction: row;
  justify-content: flex-end;
  align-items: center;
}

.columnStart {
  display: flex;
  flex-direction: column;
  justify-content: flex-start;
  align-items: center;
}

.columnAround {
  display: flex;
  flex-direction: column;
  justify-content: space-around;
  align-items: center;
}

.columnBtween {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  align-items: center;
}

.columnCenter {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
}

.columnEnd {
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  align-items: center;
}
转载请注明出处或者链接地址:https://www.qianduange.cn//article/12370.html
标签
评论
发布的文章

用HTML写B站首页

2024-06-22 07:06:37

前端开发 4: jQuery

2024-06-22 01:06:02

网页开发 HTML

2024-06-22 01:06:17

大家推荐的文章
会员中心 联系我 留言建议 回顶部
复制成功!