uniapp“手搓”一个年月选择器模态框(兼容多端)

目录

1.html部分

2.css部分

3.js部分


因某些UI库/组件库的"全面兼容"能力过于"全面"、且还要看广告😂,使用时在手机app等环境下出现各种奇奇怪怪的问题。所以本人一气之下,气了一下,被逼手搓一个年月选择器,可以兼容h5、安卓、ios和微信小程序等(其他环境有待测试)

效果图:

1.html部分

一个带遮罩层的模态框,放一个二级联动年-月选择器

html 复制代码
<view v-show="show" class="date-box"
    <!-- 遮罩层, zIndex需要根据实际情况设置 -->
    <view class="lb-picker-mask"
      style="
        backgroundColor: rgba(0, 0, 0, 0.6),
        zIndex: 1
      "
      @tap.stop="handleMaskTap">
    </view>

    <!-- 顶部按钮组 -->
    <view class="lb-picker-header-actions">
          <view class="lb-picker-action"
            @tap.stop="handleCancel">
            <text v-else
              class="lb-picker-action-cancel-text"
              >取消</text>
          </view>
          
          <view class="lb-picker-action text-blue"
            @tap.stop="handleConfirm">
            <text v-else
              class="lb-picker-action-confirm-text"
              >确定</text>
          </view>
    </view>

    <!-- 选择器区域 -->
    <view class="year-month-picker">
            <picker-view 
              class="picker-view" 
              :value="pickerValue" 
              @change="handlePickerChange"
              :indicator-style="indicatorStyle"
            >
              <!-- 年份列 -->
              <picker-view-column>
                <view 
                  class="picker-item" 
                  :class="{ 'active': pickerValue[0] === index }"
                  v-for="(year, index) in years" 
                  :key="index"
                >
                  {{ year }}年
                </view>
              </picker-view-column>

              <!-- 月份列 -->
              <picker-view-column>
                <view 
                  class="picker-item" 
                  :class="{ 'active': pickerValue[1] === index }"
                  v-for="(month, index) in months" 
                  :key="index"
                >
                  {{ month }}月
                </view>
              </picker-view-column>
            </picker-view>
     </view>
</view>

2.css部分

css 复制代码
.date-box {
    width: 750rpx;
    height: 100vh;
    position: relative;
    z-index: 9999;
}

.lb-picker-mask {
	background-color: rgba(0, 0, 0, 0.0);
	position: fixed;
	top: 0;
	right: 0;
	left: 0;
	bottom: 0;
	transition-property: background-color;
	transition-duration: 0.3s;
}

.lb-picker-header-actions {
	height: 45px;
	/* #ifndef APP-NVUE */
	box-sizing: border-box;
	display: flex;
	/* #endif */
	flex-direction: row;
	justify-content: space-between;
	flex-wrap: nowrap;
}

.lb-picker-action {
	padding-left: 10px;
	padding-right: 10px;
	/* #ifndef APP-NVUE */
	display: flex;
	/* #endif */
	flex-direction: row;
	align-items: center;
	justify-content: center;
}

.text-blue {
    color: blue;
}

.year-month-picker {
  width: 100%;
  background-color: #fff;
  border-radius: 16rpx 16rpx 0 0;
  overflow: hidden;
}

.picker-view {
  height: 400rpx;
  width: 100%;
}

.picker-item {
  height: 80.78rpx;
  line-height: 80rpx;
  text-align: center;
  font-size: 32rpx;
  color: #999;
  transition: all 0.3s ease;
}

.picker-item.active {
  color: #333;
  font-size: 36rpx;
  font-weight: bold;
}

3.js部分

目前设置不显示未来日期,可根据需要自行修改

javascript 复制代码
  data () {
    return {
      show: false,
      years: [],
      pickerValue: [0, 0], // 存放选中的年月数据
      minYear: 1900,
      maxYear: new Date().getFullYear(),
      selectedYear: 0,
      selectedMonth: 0,
      indicatorStyle: `height: 80rpx;`
    }
  },
  computed: {
    months() {// 因设置不显示未来日期,所以可选月份做处理
      const currentYear = new Date().getFullYear();
      const currentMonth = new Date().getMonth() + 1;
      // 在初始化阶段,如果selectedYear还未设置,则返回全年12个月
      if (this.selectedYear && this.selectedYear === currentYear) {
        return Array.from({ length: currentMonth }, (_, i) => i + 1);
      } else {
        return Array.from({ length: 12 }, (_, i) => i + 1);
      }
    }
  },
  created() {
    this.initYears()
    this.initDefaultValue()
  },
  methods: {
    // 初始化年份数组
    initYears() {
      this.years = []
      for (let i = this.minYear; i <= this.maxYear; i++) {
        this.years.push(i)
      }
    },
    // 初始化默认值,不显示未来的日期
    initDefaultValue() {
        const now = new Date();
        const currentYear = now.getFullYear();
        const currentMonth = now.getMonth() + 1;
        const yearIndex = this.years.indexOf(currentYear);
        // 限制月份不能超过当前月份
        const monthIndex = Math.min(this.months.indexOf(currentMonth), currentMonth - 1);
        this.pickerValue = [yearIndex, monthIndex];
        this.selectedYear = currentYear;
        this.selectedMonth = currentMonth;
    },
    // 处理选择器变化
    handlePickerChange(e) {
      const value = e.detail.value;
      this.pickerValue = [...value];
      this.selectedYear = this.years[value[0]];
      // 限制月份不能超过当前月份(仅当选择的是今年时)
      const currentYear = new Date().getFullYear();
      const currentMonth = new Date().getMonth() + 1;
      let monthIndex = value[1];
      if (this.selectedYear === currentYear) {
        monthIndex = Math.min(value[1], currentMonth - 1);
      }
      this.pickerValue[1] = monthIndex;
      this.selectedMonth = this.months[monthIndex];
    },
    handleCancel () {
      this.show = false
    },
    handleConfirm () {
      const selectedValue = `${this.selectedYear}-${this.selectedMonth.toString().padStart(2, '0')}`                    
      console.log('选中的年月', selectedValue);
    },
    // 点击遮罩层关闭模态框
    handleMaskTap () {
      this.show = false
    },
  }

以上就是年-月选择器的代码

相关推荐
web_Hsir2 小时前
uniapp + vue2 + pfdjs + web-view 实现安卓、iOS App PDF预览
android·前端·uni-app
peachSoda72 小时前
uniapp app使用命令行HBuilderX cli快捷打包iOS和Android
uni-app
2501_9160074721 小时前
跨平台 App 安全,Flutter、RN、Unity、H5 混合应用加固
android·ios·小程序·https·uni-app·iphone·webview
咕咕咕_biubiubiu21 小时前
uniapp插件——原生插件开发和使用
uni-app
芋头莎莎21 小时前
UNIAPP连接MQTT记录要点
uni-app
新 一.21 小时前
uniapp在ios上真机测试运行
ios·uni-app
2501_916007471 天前
不越狱如何查看iOS 应用的详细信息及其文件目录结构
android·macos·ios·小程序·uni-app·cocoa·iphone
李慕婉学姐1 天前
【开题答辩过程】以《基于uniapp的养宠互助服务程序设计与实现》为例,不知道这个选题怎么做的,不知道这个选题怎么开题答辩的可以进来看看
android·mysql·uni-app
李慕婉学姐1 天前
【开题答辩过程】以《基于uni-app的手账记录小程序的设计与实现》为例,不知道这个选题怎么做的,不知道这个选题怎么开题答辩的可以进来看看
java·小程序·uni-app