vue3封装年份组件

2023-12-20

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封装年份组件 的相关文章

  • Javascript DOM setAttribute 在函数调用中不起作用

    我有一个带有输入元素的 HTML 文件 我希望向其中添加一个名为 valid fieldset011 的新属性 该属性用作 AngularJS 验证器的链接 输入元素具有属性 id fieldset011 如果我使用以下脚本 包含在脚本标签
  • 第一次使用node.js - “ReferenceError:节点未定义”

    我刚刚安装了node js 我尝试编写应该检查版本的node v 但它不起作用 这是输出 gt node v ReferenceError node is not defined at repl 1 2 at REPLServer self
  • 仅单击 div 内部

    我正在为一个小网站制作教程 我只想让教程气泡可点击 因此 当我们尝试单击气泡之外的某些内容时 什么也不会发生 换句话说 我希望我的 html 不可点击 而 tutorial bubble 可点击 尝试这个 jQuery function h
  • 如何防止 gulp-notify 破坏 Windows 中的 gulp-watch?

    我正在使用吞咽通知 https www npmjs org package gulp notify插入 这是我如何在 gulpfile js 中实现它的示例 您可以看到我也在使用 gutil 和 livereload 我不知道它们是否发挥任
  • 打开 md-calendar 时滚动到当前日期

    目前正在构建一个使用 Angular Material 的应用程序 我们需要一个 md calendar 组件 我们想要自定义按钮样式和内容 因此不使用普通的 md datepicker 问题是 当 md calender 打开时 滚动位置
  • 了解 sort() 比较函数

    我正在使用一个电子商务平台 该平台无法重新排序产品属性字段的选项 这真的很糟糕 因为要插入新选项 您几乎必须删除所有现有选项并重新开始 我正在尝试在客户端进行操作 这是我正在处理的内容 这是针对鞋码的 9 EE 9 1 2 EE 10 EE
  • 在鼠标光标位置添加 cytoscape 节点

    我想在画布上的单击事件上的鼠标箭头位置添加一个 cytoscape 节点 我怎样才能做到这一点 我的方法 效果不太好 我可以通过单击创建一个节点 但无法确保创建的节点的位置位于我单击的位置 使用这样的东西 cy click function
  • 如何导入和导出 javascript ES6 类

    我是 javascript 和 nodejs 的新手 我正在使用这个项目来发展我的技能并学习新技术 目前我的项目使用多个相互依赖的类 类文件位于不同的目录中 我当前正在尝试使用 export 和 require 语句来允许在其他文件中引用类
  • 搜索深度嵌套数组以更新对象

    我有一个深层嵌套的数据结构 我有兴趣匹配数组 和数组数组 中的某个值 然后将一些数据推送到随附的数组中 例如以下是我的数组colors并伴随着的是更多颜色数组可能存在也可能不存在 var myData color green moreCol
  • 将文本大小调整为矩形 在 Canvas HTML5 中调整大小

    我是 Canvas 新手 我正在创建一个网站 以在调整矩形大小时增加文本 我尝试了很多 但没有任何效果 实际上 我希望如果我仅按其宽度调整矩形大小 向左拉伸 向右拉伸 则仅应增加文本宽度而不是字体大小 我已经完成了字体大小 但发现增加孤立文
  • 通过JS Laravel访问存储目录

    有没有办法访问storage目录 该目录已经链接到publicJS 中的目录 我正在尝试制作一个上传图片的表单 验证脚本 if request gt hasFile photos marker gt photos request gt ph
  • 获取点击的的DOM路径

    HTML div class lol a class rightArrow href a div 伪代码 rightArrow click function rightArrowParents this dom dom is the pse
  • 计算文本选择的 xy 位置

    我正在尝试使用 DOM 元素创建自己的文本选择 是的 我的意思是当您在此元素中选择文本时 您会在文本后面看到蓝色背景 这个想法是停止默认行为 蓝色 并使用我自己的元素来完成工作 方法是找到选择的 xy 位置 然后放置绝对定位的元素 我希望能
  • 如何在 ASP.NET MVC 3 的 Razor 视图中编码嵌入的 javascript?

    如何在以下上下文中正确编码 JavaScript 我的 JSON 对象中的值是由应用程序管理员设置的 因此我假设它们需要正确编码 对于 HTML 和 JavaScript 都是如此 我在用着System Web Script Seriali
  • 禁用特定 div 上的 Tab 键

    我有以下结构 div div Some content div div Some content div div 我想 禁用 div2 上的 tab 键 我的意思是按下 tab 键时 div2 的元素不会获得焦点 有没有简单的方法可以使用
  • 从 DirectionsRenderer 中获取折线或标记的事件

    我正在使用 DirectionsService 和路线方法来生成 DirectionsResult 我还使用 DirectionsRenderer 对象来显示结果 因为它非常易于使用 我在检测 Directions changed 事件时没
  • Knockout.js 安全绑定

    我想使用带有淘汰赛的安全绑定 为此我使用敲除安全绑定 js https github com brianmhunt knockout secure binding 谁能解释一下为什么下面的代码不起作用 它会抛出一个错误 未捕获 淘汰 安全
  • RoR - Rails 中的大文件上传

    我有一个 Rails Web 应用程序 允许用户上传视频 视频存储在 NFS 安装的目录中 当前的设置适用于较小的文件 但我也需要支持大文件上传 最多 4GB 当我尝试上传 4GB 文件时 它最终会发生 但从用户体验的角度来看很糟糕 上传开
  • Internet Explorer 9 是否会因数组和对象文字末尾的额外逗号而卡住?

    现代浏览器和 Node js 等环境允许您说 a 1 b 2 或 1 2 3 这在历史上一直是 Internet Explorer 的问题 Internet Explorer 9 中修复了此问题吗 对此有两种不同的答案 一种是对象初始值设定
  • 无法使用 HTML 设置未定义 jQuery UI 自动完成的属性“_renderItem”

    我使用以下代码将 jQuery UI 自动完成项呈现为 HTML 这些项目在自动完成控件中正确呈现 但我不断收到此 JavaScript 错误并且无法移动过去 Firefox 无法转换 JavaScript 参数 Chrome 无法设置未定

随机推荐