uniapp中使用picker-view选择时间

news/2024/9/18 22:29:38 标签: uni-app, 前端

picker-view 是 UniApp 中用于展示和选择数据的组件。它适用于创建多列选择器,类似于 iOS 和 Android 系统中的选择器视图。以下是 picker-view 的详细介绍,包括用法、属性和事件。
在这里插入图片描述

一 用法

<template>
  <view>
    <picker-view :value="value" @change="onChange" :indicator-style="indicatorStyle">
      <picker-view-column v-for="(column, index) in columns" :key="index">
        <view v-for="(item, itemIndex) in column" :key="itemIndex">{{ item }}</view>
      </picker-view-column>
    </picker-view>
  </view>
</template>
<script>
export default {
  data() {
    return {
      value: [0, 0], // 选中的值对应列中的索引
      columns: [     // 列数据
        ['Option 1', 'Option 2', 'Option 3'],
        ['Item 1', 'Item 2', 'Item 3']
      ],
      indicatorStyle: 'height: 50px; line-height: 50px;' // 指示器样式
    };
  },
  methods: {
    onChange(e) {
      this.value = e.detail.value; // 更新选中的值
      console.log('Selected value:', this.value);
    }
  }
};
</script>
<style scoped>
/* 可以根据需要添加自定义样式 */
</style>

二 主要属性

  • value: 数组,表示当前选中的索引值。数组的长度应与 columns 的列数一致。例如,如果有两列,每列的选项数组长度分别为 3 和
    3,则 value 应该是 [0, 0] 表示两列的默认选中项索引。
  • indicator-style: 字符串,用于设置选择器的指示器样式。可以设置如高度、背景颜色等样式。

三 主要事件

change: 当用户选择了新项时触发。事件对象的 detail.value 是更新后的选中值数组。例如:

onChange(e) {
  this.value = e.detail.value;
  console.log('Selected value:', this.value);
}
  • picker-view-column 是 picker-view 的子组件,每个 picker-view-column 代表一个列。
  • v-for 指令用于遍历 columns 和列中的选项数据。
  • e.detail.value 是一个数组,表示用户选择的每一列的索引。

四 应用场景

  • 选择日期和时间
  • 选择地区(省市区)
  • 多级分类选择

五 案例

需求 :购买商品时,可以选择取货时间,点击向右的箭头可以显示选择预约取货时间弹窗。第一次进入弹窗,默认回显当前时间,选择时间后,回显选择的时间
父组件在打开弹框时,会传一个当前时间给子组件,子组件在初始化时,根据当前时间进行回显。
在这里插入图片描述

根据传过来的时间,拿到月,时,分,然后分别在days,hours,minutes中找到对应的index,在分别把index push到value中
在这里插入图片描述

  let dayIndex = this.days.findIndex((item) => item === objTimeDay);
            let hourIndex = this.hours.findIndex((item) => item === objTimeHour);
            let minuteIndex = this.minutes.findIndex((item) => item === objTimeMinute);
            if (dayIndex > -1) {
                this.value[0] = dayIndex;
            }
            if (hourIndex > -1) {
                this.value[1] = hourIndex;
            }
            if (minuteIndex > -1) {
                this.value[2] = minuteIndex;
            }

在这里插入图片描述
在这里插入图片描述

完整代码
父组件

// 引用
import selectTime from './selectTime/index.vue';
//注册
 components: { selectAddress, selectShop, selectTime },
//使用
 <select-time ref="selectTime" @getSelectTime="getSelectTime"></select-time>

openSelectTimePopup() {
            this.$refs.selectTime.open(this.selectTimeInfo);
        },
 // 自定义事件
getSelectTime(obj) {
   this.selectTimeInfo = obj;
},

selectTime 弹窗

<template>
    <uni-popup ref="selectTime" type="bottom" :maskClick="true">
        <view class="main">
            <view class="main-header">
                <view class="main-header-title">预约取货时间</view>
                <view class="main-header-image" @click="close">
                    <image src="@/static/image/cart/sureOrder/close.png"></image>
                </view>
            </view>
            <view class="main-time">
                <picker-view v-if="visible" :indicator-style="indicatorStyle" :value="value" @change="bindChange" class="picker-view">
                    <picker-view-column>
                        <view class="item" v-for="(item, index) in days" :key="index">{{ item }}</view>
                    </picker-view-column>
                    <picker-view-column>
                        <view class="item" v-for="(item, index) in hours" :key="index">{{ item }}</view>
                    </picker-view-column>
                    <picker-view-column>
                        <view class="item" v-for="(item, index) in minutes" :key="index">{{ item }}</view>
                    </picker-view-column>
                </picker-view>
            </view>
            <view class="main-button" @click="confirm">确认</view>
        </view>
    </uni-popup>
</template>

<script>
export default {
    data() {
        return {
            days: [],
            hours: [],
            minutes: [],
            day: '',
            hour: '',
            minute: '',
            visible: true,
            value: [],
            indicatorStyle: `height: 50px;`,
            selectTimeInfo: {
                name: '',
                time: ''
            }
        };
    },
    methods: {
        confirm() {
            this.day = this.days[this.value[0]];
            this.hour = this.hours[this.value[1]];
            this.minute = this.minutes[this.value[2]];
            this.selectTimeInfo.name = this.day + ' ' + this.hour + ':' + this.minute;
            let currentDate = new Date();
            currentDate.setDate(currentDate.getDate() + this.value[0]);
            let selectYear = currentDate.getFullYear();
            let selectTimeMonth = currentDate.getMonth() + 1 < 10 ? '0' + (currentDate.getMonth() + 1) : currentDate.getMonth() + 1;
            let selectTimeDay = currentDate.getDate() < 10 ? '0' + currentDate.getDate() : currentDate.getDate();
            let time = selectYear + '-' + selectTimeMonth + '-' + selectTimeDay + ' ' + this.hour + ':' + this.minute;
            this.selectTimeInfo.time = time.slice(0, 16)+':' + '00';
            this.$emit('getSelectTime', this.selectTimeInfo);
            this.close();
        },
        init(obj) {
            // day
            for (var i = 0; i < 5; i++) {
                let date = new Date();
                let day;
                if (i === 0) {
                    day = '今天';
                } else if (i === 1) {
                    day = '明天';
                } else {
                    date.setDate(date.getDate() + i);
                    let month = date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1;
                    let d = date.getDate() < 10 ? '0' + date.getDate() : date.getDate();
                    day = month + '月' + d + '日';
                }
                this.days.push(day);
            }
            let currentDate = new Date();
            let currentMonth = currentDate.getMonth() + 1;
            let currentDay = currentDate.getDate();

            let selectTime = obj.time;
            let objTimeDate = new Date(selectTime);
            let selectMonth = objTimeDate.getMonth() + 1;
            let selectDay = objTimeDate.getDate();

            let objTimeDay;

            if (currentMonth === selectMonth && currentDay === selectDay) {
                objTimeDay = '今天';
            } else if (currentMonth === selectMonth && currentDay + 1 === selectDay) {
                objTimeDay = '明天';
            } else {
                let month = selectMonth < 10 ? '0' + selectMonth + '月' : selectMonth + '月';
                let day = selectDay < 10 ? '0' + selectDay + '日' : selectDay + '日';
                objTimeDay = month + day;
            }
            let objTimeHour = objTimeDate.getHours() < 10 ? '0' + objTimeDate.getHours() : objTimeDate.getHours();
            let objTimeMinute = objTimeDate.getMinutes() < 10 ? '0' + objTimeDate.getMinutes() + '分' : objTimeDate.getMinutes() + '分';
            this.hours = this.getHoursRange(0, 24);
            this.minutes = this.getMinuteRange(0, 61);
            let dayIndex = this.days.findIndex((item) => item === objTimeDay);
            let hourIndex = this.hours.findIndex((item) => item === objTimeHour);
            let minuteIndex = this.minutes.findIndex((item) => item === objTimeMinute);
            if (dayIndex > -1) {
                this.value[0] = dayIndex;
            }
            if (hourIndex > -1) {
                this.value[1] = hourIndex;
            }
            if (minuteIndex > -1) {
                this.value[2] = minuteIndex;
            }
        },
        getHoursRange(startHour, endHour) {
            const hours = [];
            for (let i = startHour; i <= endHour; i++) {
                let hour = i < 10 ? '0' + i : i;
                hours.push(hour);
            }
            return hours;
        },
        getMinuteRange(startMinute, endMinute) {
            let minutes = [];
            for (var i = startMinute; i < endMinute; i++) {
                let minute = i < 10 ? '0' + i + '分' : i + '分';
                minutes.push(minute);
            }
            return minutes;
        },
        bindChange(e) {
            const val = e.detail.value;
            this.value[0] = val[0];
            this.value[1] = val[1];
            this.value[2] = val[2];
        },
        open(obj) {
            this.$refs.selectTime.open();
            this.init(obj);
        },
        close() {
            this.$refs.selectTime.close();
        }
    }
};
</script>

<style lang="scss" scoped>
.main {
    width: 100%;
    height: 732rpx;
    border-radius: 32rpx 32rpx 0px 0px;
    background-color: #fff;
    box-sizing: border-box;
    .main-header {
        padding: 40rpx 0 0 40rpx;
        display: flex;
        align-items: center;
        justify-content: space-between;
        .main-header-title {
            font-family: Source Han Sans CN, Source Han Sans CN;
            font-weight: bold;
            font-size: 36rpx;
            color: #333333;
            text-align: left;
            font-style: normal;
            text-transform: none;
        }
        .main-header-image {
            width: 48rpx;
            height: 48rpx;
            margin-right: 40rpx;
            image {
                width: 100%;
                height: 100%;
            }
        }
    }
    .main-time {
        width: 100%;
        height: 400rpx;
        margin-top: 80rpx;
        .picker-view {
            width: 100%;
            height: 300rpx;
            margin-top: 20rpx;
        }
        .item {
            line-height: 100rpx;
            text-align: center;
        }
    }
    .main-button {
        width: 496rpx;
        height: 80rpx;
        background: #c11920;
        border-radius: 80rpx;
        font-family: Source Han Sans CN, Source Han Sans CN;
        font-weight: 400;
        font-size: 32rpx;
        color: #ffffff;
        line-height: 80rpx;
        text-align: center;
        font-style: normal;
        text-transform: none;
        margin: 40rpx auto 0 auto;
    }
}
</style>

如果需要设置不能选择之前的时间,可以拿到当前时间的时,分,来设置

 if (objTimeDay === '今天') {
        this.hours = this.getHoursRange(currentHour, 24);
        this.minutes = this.getMinuteRange(currentMinute, 61);
 } else {
        this.hours = this.getHoursRange(0, 24);
        this.minutes = this.getMinuteRange(0, 61);
 }

 getHoursRange(startHour, endHour) {
            const hours = [];
            for (let i = startHour; i <= endHour; i++) {
                let hour = i < 10 ? '0' + i : i;
                hours.push(hour);
            }
            return hours;
        },
 getMinuteRange(startMinute, endMinute) {
            let minutes = [];
            for (var i = startMinute; i < endMinute; i++) {
                let minute = i < 10 ? '0' + i + '分' : i + '分';
                minutes.push(minute);
            }
            return minutes;
        },

http://www.niftyadmin.cn/n/5664621.html

相关文章

Kali root密码忘记的解决方法

Kali root密码忘记的解决方法 uname -a: Linux xkm 5.10.0-21-amd64 #1 SMP Debian 5.10.162-1 (2023-01-21) x86_64 GNU/Linux背景 许久未用的虚拟机&#xff0c;密码忘了&#xff0c;按照有的搜索结果操作竟然不行&#xff08;那篇是乱写的&#xff09;。 按照这篇博客&a…

C# Action和delegate区别及示例代码

Action和delegate类似但没有返回值 Action和delegate在C#编程语言中有明显的区别&#xff0c;主要体现在它们的定义、用途和特性上。 1. 定义 Delegate&#xff1a;Delegate是C#中用于定义方法签名的类型&#xff0c;它允许将方法作为参数传递&#xff0c;或者将方法赋值给变…

Understanding the model of openAI 5 (1024 unit LSTM reinforcement learning)

题意&#xff1a;理解 OpenAI 5&#xff08;1024 单元 LSTM 强化学习&#xff09;的模型 问题背景&#xff1a; I recently came across openAI 5. I was curious to see how their model is built and understand it. I read in wikipedia that it "contains a single l…

FFmpeg源码:skip_bits、skip_bits1、show_bits函数分析

GetBitContext结构体和其相关的函数分析&#xff1a; FFmpeg中位操作相关的源码&#xff1a;GetBitContext结构体&#xff0c;init_get_bits函数、get_bits1函数和get_bits函数分析 FFmpeg源码&#xff1a;skip_bits、skip_bits1、show_bits函数分析 一、skip_bits函数 skip…

EfficientFormerV2:重新思考视觉变换器以实现与MobileNet相当的尺寸和速度。

摘要 https://arxiv.org/pdf/2212.08059 随着视觉变换器&#xff08;ViTs&#xff09;在计算机视觉任务中的成功&#xff0c;近期的研究尝试优化ViTs的性能和复杂度&#xff0c;以实现在移动设备上的高效部署。提出了多种方法来加速注意力机制&#xff0c;改进低效设计&#xf…

Rust GUI框架Tauri V1 入门

文章目录 Tauri介绍Vite开始创建 Rust 项目 调用指令window.__TAURI_INVOKE__.invoke is undefined 问题 参考资料JavaScript 模块Vue 框架Vue RouteviteNuxt gitignore文件上传到csdn gitcode网站端本地端 gitcode发布 Tauri介绍 Tauri是一款用Rust构建的开源框架&#xff0c…

电池管理仓的拆解

拆解视频里面可以学习到大厂的设计思想和创意&#xff0c;接触到比较行业化的设计方案&#xff0c;从而提升设计电路的水平。 电池仓&#xff1a; 电池管家的芯片用的就是前段时间了解到的STM32G030C8T6&#xff0c;便宜好用的典范&#xff1a; 弧形走线较为推荐&#xff1a; …

SpringCloud解读

在Java中&#xff0c;Spring Cloud是一个基于Spring Boot的一站式企业级分布式应用开发框架。它整合了多种分布式系统的常见模式&#xff0c;如配置管理、服务发现、断路器、智能路由、微代理、控制总线等&#xff0c;使得开发者能够轻松地构建分布式系统。Spring Cloud的核心组…