vue3封装年份组件

2023-12-21

ant框架年份组件
看了ant框架针对于年份不能自定义插槽内容所以放弃用ant框架年份组件,自定义插槽内容是想实现年份下方可以加小圆点的需求,因加小圆点需求必须实现,决定自己封装组件来实现需求,自己实现的效果呢类似于ant年份控件 在这里做一下记录。
效果图如下:
在这里插入图片描述
1.YearPicker.vue

<template>
  <div class="year-picker" >
    <q-input
      outlined
      v-model="contentValue"
      dense
      @blur="blurEvent"
      @focus="inputFocus"
      placeholder="选择年份"
      clearable
      @clear="clearHandle"
      class="col"
    >
    </q-input>
    <transition name="fade">
      <div class="year-picker__year-box" v-if="showYearContent">
        <div class="year-picker__year-title">
          <span class="to-left" @click="toLeft()"><DoubleLeftOutlined style="rgba(0, 0, 0, 0.45)"/></span>
          <span class="to-middle">{{yearStart}}-{{yearEnd-1}}</span>
          <span class="to-right" @click="toRight()"><DoubleRightOutlined style="rgba(0, 0, 0, 0.45)"/></span>
        </div>
        <div class="year-picker__year-content" >
         <span v-for="(item,index) in yearList" :key="index" style="position: relative;">
          <div  class="listItem" :class="{listItemBgC: item === checkedIndex,'year-disable':yearDis(item)}" @click="chooseYear(item,index)">{{item}}</div>
           <div :class="getAllYear(item)" ></div>
         </span>
        </div>
      </div>
    </transition>
  </div>
</template>
<script>
import { ref, shallowRef, watch, nextTick, onMounted, inject,reactive ,computed,toRefs,getCurrentInstance,watchEffect} from 'vue'
import {DoubleLeftOutlined,DoubleRightOutlined} from '@ant-design/icons-vue'
export default {
  name: 'index',
  components:{
    DoubleLeftOutlined,
    DoubleRightOutlined
  },
  props: {
    yearDisable: {
      type: String,
      default: 'no'
    },
    contentValue: {
      type: Number,
    },
    allDataList:{
      type: Array,
      default: ()=>{
        return []
      }
    },
  },
  setup(props,context) {

    const { yearDisable } = toRefs(props);

    const checkedIndex = ref()

    const state = reactive({
      yearLists: [],
      showYearContent: false,
      yearStart: 2010,
      yearEnd: 2030,
      blurIndex:null,
      allDataList:[],
    })

    const contentValue = ref()

    watch(() => props.contentValue, (newvalue) => {
      if(newvalue){
        contentValue.value = newvalue
        context.emit('handlerInput',newvalue)
      }
    }, {immediate: true})

    watch(() => props.allDataList, (value) => {
      if(!value) return
      state.allDataList = value
    }, {immediate: true})

    const inputFocus = ()=> {
      state.showYearContent = true
    }

    const blurEvent= (e)=> {
      state.showYearContent = false
    }

    const chooseYear=(year,index)=> {
      if (year > yearDis.value) return
      state.showYearContent = false
      checkedIndex.value = year
      context.emit('handlerInput', year)
    }

    const toLeft=()=> {
      state.yearStart -= 20
      state.yearEnd -= 20
      state.showYearContent = true
    }

    const toRight=()=> {
      state.yearStart += 20
      state.yearEnd += 20
      state.showYearContent = true
    }

    const yearDis = computed(()=>{
      return function (y) {
        switch (yearDisable.value) {
          case 'before': {
            return y < new Date().getFullYear()
          }
            break;
          case 'no': {
            return false
          }
            break;
          case 'after': {
            return y > new Date().getFullYear()
          }
        }
      }
    })

    const yearList = computed(()=>{
      let arr = []
      for (let i = state.yearStart; i < state.yearEnd; i++) {
        arr.push(i)
      }
      return arr
    })

    const clearHandle = (value)=>{
      checkedIndex.value = ''
    }
	
	//实现年份下方加小圆点事件
    const getAllYear = (year) => {
      if(state.allDataList.findIndex(mon =>  mon === year) !== -1){
        return 'checkbox1'
      }else{
        return 'defultbox1'
      }
    }

    return {
      ...toRefs(state),
      yearDis,
      getAllYear,
      yearList,
      checkedIndex,
      clearHandle,
      inputFocus,
      contentValue,
      blurEvent,
      chooseYear,
      toLeft,
      toRight,
    }
  },
}
</script>

<style scoped lang="scss">
.checkbox1{
  position: absolute;
  left: 50%;
  height: 5px;
  width: 8px;
  border-radius: 5px;
  background-color: #ff9800;
  transform: translate3d(-50%,0,0)
}
.defultbox1{
  position: absolute;
  left: 50%;
  height: 5px;
  width: 8px;
  border-radius: 5px;
}
.year-picker {
  ::v-deep(.q-field--dense .q-field__control){
    height: 32px!important;
  }
  ::v-deep(.q-field--dense .q-field__marginal){
    height: 32px!important;
  }

  .col{
    box-sizing: border-box;
    margin: 0;
    color: rgba(0, 0, 0, 0.88);
    font-size: 14px;
    height: 32px!important;
    position: relative;
    display: inline-flex;
    align-items: center;
    background: #ffffff;
    border-radius: 6px;
    transition: border 0.2s,box-shadow;
  }
  .col:hover{
    border: none!important;
    margin: 0;
  }

  margin-left: 20px;
  display: inline-block;
  border-radius: 5px;
  .year-picker__icon {
    position: absolute;
    transform: translate(-26px, 10px);
    color: #d9d9d9
  }
  .year-picker__input--real:hover {
    border: 1px solid rgba(0, 122, 244, 0.8);
  }

  .year-picker__year-title {
    height: 40px;
    width: 270px;
    border-top: 1px solid #d4d4d4;
    border-bottom: 1px solid #d4d4d4;
    display: flex;
    justify-content: space-around;
    align-items: center;
    .to-middle{
      font-weight: bold;
      color: #666666;
    }
    span {
      color: #525252;
      cursor: pointer;
    }

    span:active {
      opacity: .5;
    }
  }

  .year-picker__year-box {
    position: absolute;
    z-index: 10;
    background: #ffffff;
    border-radius: 5px;
    border: 1px solid #eeeeee;
    box-shadow: 0 0 .38rem 0 rgba(0, 0, 0, 0.1);
    transform: translateY(-32px);
    left:36px;
    top:72px;
  }
  .year-picker__year-content {
    padding-top: 20px;
    width: 270px;
    height: 250px;
    display: flex;
    flex-wrap: wrap;
    justify-content: space-around;
    .listItem{
      color: #525252;
      font-size: 14px;
      width: 48px;
      height: 25px;
      display: flex;
      justify-content: center;
      align-items: center;
      margin-bottom: 2px;
    }
    .listItem:hover{
      cursor: pointer;
    }
    .listItemBgC{
      background-color: #0067c0;
      color:white;
      border-radius: 3px;
    }
    .year-disable {
      background: #f5f5f5;
    }
    .year-disable:hover {
      cursor: no-drop;
      background: #f5f5f5;
    }
  }
}
.fade-enter,
.fade-leave-to {
  opacity: 0;
  transform: translateY(-30px);
}
/* 过程 */
.fade-enter-active {
  transition: all 0.5s;
}
/* 结束 */
.fade-enter-to {
  opacity: 1;
}
.fade-leave-active {
  transition: all 0.5s;
}

.dark {
  border: 1px solid blue;
  color: #8099b3;

  .year-picker__input {
    background: #003366;
    color: #8099b3;;
  }

  .year-picker__input--real {
    border: 1px solid blue;
    height: 32px;
  }

  .year-picker__input::placeholder {
    color: #1c5389;
  }

  .year-picker__year-title {
    border-top: 1px solid blue;
    border-bottom: 1px solid blue;

    span {
      color: #8099b3;
    }
  }

  .year-text:hover {
    cursor: pointer;
    background: rgba(157, 219, 252, 0.41);
    border-radius: 3px;
  }

  .year-picker__year-content {
    .year-text {
      color: #8099b3;
    }

    .year-disable {
      background: #133558;
    }

    .year-disable:hover {
      cursor: no-drop;
      background: #133558;
    }
  }
}
</style>


vue 使用组件

 <YearPicker :contentValue="contentValue" @handlerInput="handlerInput" :year-disable="'no'" :allDataList="allDataList"/>
 const state =  reactive({
      contentValue:'', //选中的年份
      allDataList:[2018,2019],// 加这个属性呢是实现年份下方加黄色小圆点
 })
 //组件里选中的年份传过来的事件
 const handlerInput =  (value) =>{
     console.log(value)
    state.contentValue = value
  }

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

vue3封装年份组件 的相关文章

  • 跨域XMLHttp请求

    这是我的情况 我有一台 Web 服务器机器 一台客户端机器和第三台运行一些侦听 XMLHttpRequest 的程序的机器 客户端从客户端计算机访问网络服务器 进行一些更改 然后单击 保存 此时 数据被发送回网络服务器和第三台机器 所有这些
  • 如何在 Firefox 控制台中访问附加内容脚本?

    我为 Firefox 和 Chrome 开发了一个插件 它有内容脚本 我想在浏览器选项卡的控制台中访问它们 在 Firefox 上网页控制台 https developer mozilla org en US docs Tools Web
  • pubnub 和 head.js

    有没有人成功整合过pubnub http www pubnub com 和 head js 正确吗 Pubnub http www pubnub com 希望我将他们的脚本放在页面底部并带有 div 就在它前面的标签 这可以确保在最后调用
  • 使用 javascript 更改 div 颜色

    div style height 20px width 100 background color 000000 div br
  • 在 Javascript 中获取第一个数字出现后的子字符串

    我正在尝试提取第一个数字之后 并包括 的字符 ABC 123SD gt 123SD 123 gt 123 123SD gt 123SD ABC gt 我当前的解决方案如下 var string1 ABC 123SD var firstDig
  • Angular 2 Material 2 日期选择器日期格式

    我不知道如何更改材料2日期选择器的日期格式 我已阅读文档 但我不明白我实际上需要做什么 datepicker默认提供的输出日期格式为f e 6 9 2017 我想要实现的目标是将格式更改为类似的格式9 Jun 2017或任何其他 文档htt
  • 仅单击 div 内部

    我正在为一个小网站制作教程 我只想让教程气泡可点击 因此 当我们尝试单击气泡之外的某些内容时 什么也不会发生 换句话说 我希望我的 html 不可点击 而 tutorial bubble 可点击 尝试这个 jQuery function h
  • Javascript - 在加载所有图像后执行

    看了别人的问题我想 window onload 会回答我的问题 我已经尝试过这个 但它会在页面加载时立即执行代码 而不是在图像加载之后 如果有什么区别的话 图像来自 CDN 并且不是相对的 有人知道解决办法吗 我没有使用 jQuery 想要
  • 在 jQuery 可排序中对多个选定项目进行排序?

    我试图在 jQuery 可排序集中选择多个项目 然后将选定的项目一起移动 这是我的弱点开始尝试使其发挥作用 http jsfiddle net benstenson CgD8Y 这是代码 HTML div class container d
  • 为什么 Web Worker 性能在 30 秒后急剧下降?

    我正在尝试提高在网络工作人员中执行时脚本的性能 它旨在解析浏览器中的大型文本文件而不会崩溃 一切都运行得很好 但我注意到使用网络工作者时大文件的性能存在严重差异 于是我做了一个简单的实验 我在同一输入上运行脚本两次 第一次运行在页面的主线程
  • 如何在 Laravel 5.4 中加载 Vue 组件?

    我已经运行 npm run watch 并收到了消息 This dependency was not found in resources assets js app js To install it you can run npm ins
  • 为什么将 x 和 y 设置为 0 时 svg 文本会消失?

    我刚刚开始阅读有关svg我提出了以下问题 我正在创建一个简单的svg with a text里面如下图所示 从我的阅读中我了解到x and y of the text标签声明文本在标签内的位置svg space 为什么当我同时设置x and
  • 在 Fabric.js 中按宽度/高度在另一个画布对象内居中和缩放画布对象

    Goal 将一个对象 水平和垂直 置于另一个对象 矩形或组 的中心canvas via Fabric js或者通过Javascript保持原始对象的长宽比相同 但也不超过父对象的宽度 高度比例 父对象 矩形或组 不会居中于canvas元素
  • 获取点击的的DOM路径

    HTML div class lol a class rightArrow href a div 伪代码 rightArrow click function rightArrowParents this dom dom is the pse
  • 从 DirectionsRenderer 中获取折线或标记的事件

    我正在使用 DirectionsService 和路线方法来生成 DirectionsResult 我还使用 DirectionsRenderer 对象来显示结果 因为它非常易于使用 我在检测 Directions changed 事件时没
  • RoR - Rails 中的大文件上传

    我有一个 Rails Web 应用程序 允许用户上传视频 视频存储在 NFS 安装的目录中 当前的设置适用于较小的文件 但我也需要支持大文件上传 最多 4GB 当我尝试上传 4GB 文件时 它最终会发生 但从用户体验的角度来看很糟糕 上传开
  • JavaScript:测试与执行

    我想知道检查字符串 例如邮件 密码等 的最佳方法是什么 i exec a vs i test a exec返回值 test true test 1 way var mail req body mail if check mail exec
  • Node.js - 重载函数

    有没有一种方法可以重载node js中的函数 类似于 noSuchMethod https developer mozilla org en JavaScript Reference Global Objects Object noSuch
  • Flowtype 属性“msg”缺失为 null 或未定义

    我发现 Flow 很难用 我明白那个Array find可以返回或未定义 因此 通过阅读以下内容 github Array find on Array 引发 https github com facebook flow issues 351
  • 从输入类型编号获取无效值

    我正在使用输入类型数字 当它无效时 我如何从中获取值 例如 使用类型编号并仅打印 e 这本身是无效的 我正在使用 React 但我认为这个问题非常普遍 onChange event console log event target valu

随机推荐