本组件中基于vue开发,可以在vue项目中添加后自由使用。

目录

效果展示

  • 一个月28天的时间块初始状态
  • <mark>补充</mark>:如果想获得用户选择的实时月份天数,可以使用moment(“2022-02”, “YYYY-MM”).daysInMonth()
  • 2022-02是用户选择的月份,具体可以使用月份选择器获取

  • 两个时间块联动用法:第一个时间块的选择块是第二个时间块的禁用块

功能描述

  • 可清空
  • 可设置块个数
  • 可设置禁用块
  • 点击选择后拿到选择块数组
  • 可联动使用实现不可重复选择相同时间的效果

结构代码

<template>
    <!-- 时间块组件 -->
  <div class="c-time-block">
      <div class="block-box">
          <div :class="['block', `${item.status}`]" v-for="item in blocks" :key="item.text" @click="sel_block(item.text)">
              {
  {item.text}}
          </div>
      </div>
  </div>
</template>
<script>
  • blocks保存所有块,text是块文本,status是块状态
  • 块样式由块状态决定

逻辑代码

import {
    blocks } from './data/time.js'
import {
    deepCopy } from './js/c_common.js'
export default {
   
  name: 'c-time-block',
  data() {
   
    return {
   
        blocks: deepCopy(blocks),
        selected_blocks: []
    }
  },
  props: {
   
      clear: {
   
          type: Boolean,
          default() {
   
              return false
          }
      },
      num: {
   
          type: Number,
          default() {
   
              return 14
          }
      },
      disabled: {
   
          type: Array,
          default() {
   
              return []
          }
      }
  },
  watch: {
   
      disabled(n, o){
   
            this.blocks.forEach(blo => {
   
                if(n.includes(blo.text)) {
    // 未选禁用
                    blo.status = 'disabled'
                } else {
    // 解除禁用
                    blo.status = blo.status==='disabled'?'unselected':blo.status
                }
            })
      },
      clear(n, o) {
   
          if(n) {
   
            this.blocks.map(i => i.status='unselected')
            this.selected_blocks = []
            this.$emit('getBlocks', this.selected_blocks)
          }
      }
  },
  methods: {
   
      sel_block(b) {
   
          if(!this.disabled.includes(b)) {
   
                if(!this.selected_blocks.includes(b)) {
    // 点击未选
                    this.blocks.forEach(blo => {
   
                        if(blo.text===b) {
   
                            blo.status = 'selected'
                        }
                    })
                    this.selected_blocks.push(b)
                    this.$emit('getBlocks', this.selected_blocks)
                } else {
    // 点击已选
                    this.blocks.forEach(blo => {
   
                        if(blo.text===b) {
   
                            blo.status = 'unselected'
                        }
                    })
                        let idx = this.selected_blocks.findIndex(bb => bb===b)
                        this.selected_blocks.splice(idx, 1)
                        this.$emit('getBlocks', this.selected_blocks)
                }
          }
          
      }
  },
  created() {
   
      // 时间块初始化
      let blocks_temp = []
      for(let i=1;i<=this.num;i++) {
   
          let s = this.disabled.find(ss => ss === i)? 'disabled':'unselected'
          let b = {
   
              text: i,
              status: s
          }
        blocks_temp.push(b)
      }
      this.blocks = blocks_temp
  }
}
  • 首先在created里面进行初始化,根据设置的Num确定时间块个数,并根据初始设置的禁用块渲染
  • sel_block:点击禁用块无效,点击未选中和选中分别有不同的动作
  • disabled:联动使用时监听禁用块变化,禁用或者解除禁用有不同动作
  • clear:在父组件内传值clear由false变为true的时候触发时间块的清空操作

组件应用

// 联动使用,时间块1的选择是时间2的禁用;时间2的选择是时间1的禁用
<c-time-block :num="28"  :disabled="time2" :clear="clear_blo" @getBlocks="getBlocks1"></c-time-block>
<c-time-block :num="28"  :disabled="time1" :clear="clear_blo" @getBlocks="getBlocks2"></c-time-block>

import cTimeBlock from './components/c-time-block/index'

components: {
   
    cTimeBlock
}
  • import引入——>组件注册——>使用
  • num:设置时间块个数
  • disabled:设置禁用时间块,array

事件钩子


// 获取time1
getBlocks1(sel) {
   
   this.time1= sel
},
// 获取time2
getBlocks2(sel) {
   
   this.time2= sel
},
  • getBlocks1/getBlocks2:拿到选择的时间块

github

完整代码点击这里