微信小程序的日期区间选择组件的封装和使用

news2025/7/6 10:19:04

组件化开发是一种将大型软件系统分解为更小、更易于管理和复用的独立模块或组件的方法。这种方法在现代软件开发中越来越受到重视,尤其是在前端开发领域。微信小程序的日期区间选择组件的使用
在这里插入图片描述

wxml 代码

<view>
  <view bind:tap="chooseData">{{ rendunTime || '请选择开始时间和结束时间'}}</view>
  <sx-data-picker show="{{isShowData}}" bind:confirm="getDataSlot"></sx-data-picker>
</view>

js 代码

Page({
  data: {
    isShowData:false,
    rendunTime:""
  },
  chooseData(){
    this.setData({
      isShowData:!this.isShowData
    })
  },
  getDataSlot(e){
    let time = `${e.detail.start}${e.detail.end}`
    this.setData({
      rendunTime:time
    })
  }
})

微信小程序的日期区间选择组件的封装

wxml布局代码

<!-- 遮罩层的样式 -->
<view class="page" bindtouchmove="touchMove" hidden="{{!hideModal}}" wx:if="{{show}}">
  <!-- 内容视图样式 -->
  <view class="content" style="transform:translateY({{translateY}}px);" animation="{{animate}}">
    <view class="header" bindtouchstart="touchStart">
      <image class="headerFork" bindtap="hideModal" src="/static/images/close.png"></image>
      <view class="time" >
        <view class="time_text">
          <view>开始时间:{{startyear}}年{{startmonth}}月{{startday}}日</view>
        </view>
        <view class="item_time">
          <picker-view indicator-class="picker_active" mask-class="mask" value="{{startvalue}}" data-type="start" style="width: 100%; height: 200rpx;" bindchange="bindChange">
            <picker-view-column>
              <view class="timeText" wx:for="{{years}}" wx:key="index">{{item}}年</view>
            </picker-view-column>
            <picker-view-column>
              <view class="timeText" wx:for="{{months}}" wx:key="index" bindchange="monthChange">{{item}}月</view>
            </picker-view-column>
            <picker-view-column>
              <view class="timeText" wx:for="{{days}}" wx:key="index">{{item}}日</view>
            </picker-view-column>
          </picker-view>
        </view>
        <view class="time_text">
          <view>结束时间:{{endyear}}年{{endmonth}}月{{endday}}日</view>
        </view>
        <view class="item_time">
          <picker-view indicator-class="picker_active" mask-class="mask" style="width: 100%; height: 200rpx;" value="{{endvalue}}" data-type="end" bindchange="bindChange">
            <picker-view-column>
              <view class="timeText" wx:for="{{years}}" wx:key="index">{{item}}年</view>
            </picker-view-column>
            <picker-view-column>
              <view class="timeText" wx:for="{{months}}" wx:key="index">{{item}}月</view>
            </picker-view-column>
            <picker-view-column>
              <view class="timeText" wx:for="{{days}}" wx:key="index">{{item}}日</view>
            </picker-view-column>
          </picker-view>
        </view>
      </view>
    </view>
    <!-- 按钮 -->
    <view class="button" bindtap="confirm">
      <view class="view">确认</view>
    </view>
  </view>
</view>

wxss样式代码

.page {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 1000;
  width: 100vw;
  height: 100vh;
  background: rgba(0, 0, 0, 0.5);
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
}
 
.content {
  width: 100vw;
  background: rgba(255, 255, 255, 1);
  border-radius: 16rpx 16rpx 0rpx 0rpx;
}
 
.header {
  width: 100vw;
  padding: 24rpx 50rpx;
  box-sizing: border-box;
}
 
.header .headerFork {
  position: absolute;
  top: 26rpx;
  left: calc(100% - 60rpx);
  width: 36rpx;
  height: 36rpx;
  opacity: 0.3;
  border-radius: 50%;
}
 
.headerContent {
  width: 198rpx;
  height: 198rpx;
  border-radius: 8rpx;
}
 
.headerContent .headerContentImage {
  width: 100%;
  height: 100%;
  border-radius: 8rpx;
}
 
.header .money {
  font-size: 48rpx;
  font-family: Medium;
  font-weight: 500;
  color: #FA5151;
  margin-left: 24rpx;
}
 
.smallMoney {
  font-size: 30rpx;
}
 
.header>.headerNumber>.name {
  height: 30rpx;
  font-size: 30rpx;
  font-family: Medium;
  font-weight: 500;
  color: #181818;
  line-height: 30rpx;
}
 
.button {
  width: 100vw;
  padding: 32rpx 24rpx;
  border-top: 2rpx solid #f5f5f5;
  position: relative;
  z-index: 100;
}
 
.button .view {
  width: calc(100% - 48rpx);
  height: 80rpx;
  border-radius: 50rpx;
  line-height: 80rpx;
  text-align: center;
  font-size: 30rpx;
  font-family: Regular;
  font-weight: 400;
  color: #fff;
  background: #409eff;
  opacity: 1;
}
.timeText{
  font-size: 28rpx;
  line-height: 68rpx;
  font-family: Medium;
  font-weight: 500;
  color: #181818;
  text-align: center;
}
.time_text {
  text-align: center;
  margin-top: 32rpx;
  margin-bottom: 14rpx;
  font-size: 30rpx;
  font-family: Medium;
  font-weight: 500;
  color: #181818;
}

js 逻辑代码

 
let pageY = 0
const date = new Date()
const years = []
const months = []
const days = []
// 获取当前日期的年月日
var currentYear = new Date().getFullYear();
var currentMonth = new Date().getMonth() + 1;
var currentDate = new Date().getDate();
// 当前月份包含的天数
var maxDate = new Date(currentYear, currentMonth, 0).getDate();
// 所有的年份
for (let i = 1990; i <= date.getFullYear(); i++) {
  years.push(i)
}
// 所有的月份
for (let i = 1; i <= 12; i++) {
  months.push((i + "").padStart(2, '0'))
}
// 当前月份包含的所有天数
for (let i = 1; i <= maxDate; i++) {
  days.push((i + "").padStart(2, '0'))
}
 
Component({
  options: {
    styleIsolation: 'isolated', //样式隔离
  },
  /**
   * 组件的属性列表
   */
  properties: {
    show: {
      type: Boolean,
      value: false
    },
  },
  /**
   * 数据监听
   */
  observers: {
    'show': function (value) {
      if (value) {
        this.showModal()
      } else {
        this.hideModal()
      }
    }
  },
  /**
   * 组件的初始数据
   */
  data: {
    // 时间控件
    years: years,
    months: months,
    days: days,
    // 开始日期文字
    startyear: '',
    startmonth: '',
    startday: '',
    // 时间控件开始时间
    startvalue: [],
    // 结束日期文字
    endyear: '',
    endmonth: '',
    endday: '',
    // 时间控件结束时间
    endvalue: [],
    animate: '',
    hideModal: false, //模态框的状态  false-隐藏  true-显示
  },
  /**
   * 组件的方法列表
   */
  methods: {
    // 显示遮罩层
    showModal() {
      this.setData({
        hideModal: true, //点击之后是否显示
      })
      const animation = wx.createAnimation({
        duration: 500, //反应的时间
        timingFunction: 'ease', //动画效果
      })
      // 先显示背景再执行动画,translateY(0)偏移量为0代表显示默认高度
      setTimeout(() => {
        animation.translateY(0).step()
        this.setData({
          animate: animation.export()
        })
        this.timeShow()
      }, 0)
    },
    // 隐藏遮罩层
    hideModal() {
      const animation = wx.createAnimation({
        duration: 500,
        timingFunction: 'ease',
      })
      // 设置为100vh可以确保滚动到底部,可以按照自己的内容高度设置,能够滑到底部即可
      animation.translateY('100vh').step()
      this.setData({
        animate: animation.export(),
      })
      // 先执行动画,再隐藏组件
      setTimeout(() => {
        this.setData({
          hideModal: false
        })
        this.triggerEvent('hideModal', true)
      }, 300)
 
    },
    // 移动
    touchMove(e) {
      const clientY = e.changedTouches[0].clientY
      if (clientY - pageY > 0 && clientY - pageY > 50) {
        this.hideModal()
      }
    },
    // 触摸开始
    touchStart(e) {
      pageY = e.changedTouches[0].clientY
    },
    // 时间更改
    bindChange(e) {
      const val = e.detail.value;
      var newDays = [];
      var maxDate = new Date(this.data.years[val[0]], this.data.months[val[1]], 0).getDate();
      // 选择月份包含的所有天数
      for (let i = 1; i <= maxDate; i++) {
        newDays.push((i + "").padStart(2, '0'))
      }
      // 时间文字内容更改
      if (e.target.dataset.type == 'start') { //开始时间
        //判断月份是否发生改变---月份改变 对应的当月包含天数改变并且定位到1号
        if (this.data.startmonth != this.data.months[val[1]]) {
          this.setData({
            days: newDays,
            startvalue: [val[0], val[1], 0],
            startyear: this.data.years[val[0]],
            startmonth: this.data.months[val[1]],
            startday: days[0]
          })
        } else {
          this.setData({
            startyear: this.data.years[val[0]],
            startmonth: this.data.months[val[1]],
            startday: this.data.days[val[2]]
          })
        }
      } else { //结束时间
        //判断月份是否发生改变---月份改变 对应的当月包含天数改变并且定位到1号
        console.log(days[0])
        if (this.data.endmonth != this.data.months[val[1]]) {
          this.setData({
            days: newDays,
            endvalue: [val[0], val[1], 0],
            endyear: this.data.years[val[0]],
            endmonth: this.data.months[val[1]],
            endday: days[0]
          })
        } else {
          this.setData({
            days: newDays,
            endyear: this.data.years[val[0]],
            endmonth: this.data.months[val[1]],
            endday: this.data.days[val[2]]
          })
        }
      }
    },
    timeShow() {
      // 获取时间控件---默认的开始时间和结束时间
      var defaultYear = years.length - 1;
      var defaultMonth = currentMonth;
      var defaultDate = currentDate - 1;
      this.setData({
        // 开始日期文字
        startyear: currentYear,
        startmonth: currentMonth,
        startday: currentDate,
        // 时间控件开始时间
        startvalue: [defaultYear, defaultMonth, defaultDate],
        // 结束日期文字
        endyear: currentYear,
        endmonth: currentMonth,
        endday: currentDate,
        // 时间控件结束时间
        endvalue: [defaultYear, defaultMonth, defaultDate],
      })
    },
    // 确认按钮事件
    confirm() {
      let {
        startyear,
        startmonth,
        startday,
        endyear,
        endmonth,
        endday
      } = this.data
      let obj = {
        start: startyear + '-' + startmonth + '-' + startday, //开始时间
        end: endyear + '-' + endmonth + '-' + endday //结束时间
      }
      this.hideModal()
      this.triggerEvent('confirm', obj)
    },
  },
})

如果这篇文章对你有所帮助,欢迎点赞、分享和留言,让更多的人受益。感谢你的细心阅读,如果你发现了任何错误或需要补充的地方,请随时告诉我,我会尽快处理。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2227192.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

flask自学教程(二)

文章目录 前言一、中型flask目录二、大型flask目录1.启动文件run.py定义2.实例创建文件定义&#xff08;app/__init__.py&#xff09;3.配置项config.py4. app/routes下的__init__.py5. 定义一个路由并写一个静态页面6. 模型文件7.static目录8.requirements.txt依赖 3.flask&am…

威胁 Windows 和 Linux 系统的新型跨平台勒索软件:Cicada3301

近年来&#xff0c;网络犯罪世界出现了新的、日益复杂的威胁&#xff0c;能够影响广泛的目标。 这一领域最令人担忧的新功能之一是Cicada3301勒索软件&#xff0c;最近由几位网络安全专家进行了分析。他们有机会采访了这一危险威胁背后的勒索软件团伙的成员。 Cicada3301的崛…

C/C++ 随机数生成方法

1. 使用 rand() 和 srand() - 库: <stdlib.h> 或 <cstdlib> - 特点: 伪随机数生成器&#xff0c;简单易用。 - 示例: #include <stdlib.h> #include <time.h> int main() { srand(time(NULL)); // 初始化随机数生成器 int random_nu…

openEuler 系统进程管理全攻略

openEuler 系统进程管理全攻略 一、前言 在 openEuler 操作系统中&#xff0c;进程管理是系统管理的重要组成部分。有效地管理进程可以提高系统的性能、稳定性和安全性。本文将详细介绍 openEuler 系统中与进程管理相关的操作、工具和命令&#xff0c;包括它们的应用场景和使…

Jenkins发布vue项目,版本不一致导致build错误

问题一 yarn.lock文件的存在导致在自动化的时候&#xff0c;频频失败问题二 仓库下载的资源与项目资源版本不一致 本地跑好久的一个项目&#xff0c;现在需要部署在Jenkins上面进行自动化打包部署&#xff1b;想着部署后今后可以省下好多时间&#xff0c;遂兴高采烈地去部署&am…

技术成神之路:设计模式(二十一)外观模式

相关文章&#xff1a;技术成神之路&#xff1a;二十三种设计模式(导航页) 介绍 外观模式&#xff08;Facade Pattern&#xff09;是一种结构型设计模式&#xff0c;它为子系统中的一组接口提供一个统一的接口。外观模式定义了一个高层接口&#xff0c;使得子系统更容易使用。 …

十六:Python学习笔记-- 爬虫(2)requests 模块详解

目录 安装 requests 模块 基本请求方法 GET 请求 POST 请求 PUT 请求 DELETE 请求 添加请求头&#xff1a; 处理查询参数&#xff1a; 文件上传&#xff1a; 常见响应状态码 访问超时 cookie的查询和设置 查询 Cookies 设置 Cookies 设置爬虫代理 小试牛刀 安装 …

QStringList 使用详解

QT开发之路 企业级开发系列文章&#xff0c;主要目标快速学习、完善、提升 相关技能 高效完成企业级项目开发 分享在企业中积累的实用技能和经验。 通过具体的编码过程、代码示例、步骤详解、核心内容和展示的方法解决遇到的实际问题。 转载请附上文章出处与本文链接。 QStrin…

尚硅谷 | Nginx | 学习笔记

尚硅谷 | Nginx | 学习笔记 尚硅谷Nginx教程由浅入深&#xff08;一套打通丨初学者也可掌握&#xff09;_哔哩哔哩_bilibili 文章目录 尚硅谷 | Nginx | 学习笔记一、Nginx相关概念1.Nginx是什么2.正向代理和反向代理正向代理反向代理 3.负载均衡和动静分离负载均衡动静分离 二…

AtCoder ABC376A-D题解

个人觉得 ABC 变得越来越难了/kk/kk/kk 比赛链接:ABC376 Problem A: Code #include <bits/stdc.h> using namespace std; int main(){int N,C;cin>>N>>C;for(int i1;i<N;i)cin>>T[i];int ans0,pre-1e5;for(int i1;i<N;i){if(T[i]-pre>C){…

后台管理系统的通用权限解决方案(五)SpringBoot整合hibernate-validator实现表单校验

1 hibernate-validator介绍 早期的网站&#xff0c;用户输入一个邮箱地址&#xff0c;需要将邮箱地址发送到服务端&#xff0c;服务端进行校验&#xff0c;校验成功后&#xff0c;给前端一个响应。 有了JavaScript后&#xff0c;校验工作可以放在前端去执行。那么为什么还需要…

【02基础】- RabbitMQ基础

目录 2- RabbitMQ2-1 介绍和安装安装 2-2 RabbitMQ 快速入门2-3 RabbitMQ 数据隔离 3- Java客户端3-1 快速入门AMQP快速入门&#x1f4d1;小结&#xff1a;SpringAMQP如何收发消息&#xff1f; 3-2 WorkQueues 任务模型案例-使用 WorkQueue 单队列绑定多消费者&#x1f4d1;小结…

uniapp开发【选择地址-省市区功能】,直接套用即可

一、效果展示 二、代码 <template><view><view class="user_info"><view class="item"

.NET Core WebApi第3讲:第一个WebApi项目、WebApi开发三种模型

一、.NEt Core 1、运行模板项目 1&#xff09;仍然有controllers&#xff0c;说明WebApi是基于MVC模式的&#xff0c;只是对比之下这里没有MVC中的views。 因为WebApi只会向前台发送数据&#xff0c;不会向前台发送HTML页面。 2、验证模板项目的api 1&#xff09;法1&#xf…

地球上的中国:世界地图概览

目录 地理空间数据可视化描绘地图导入Python包参数设置true自定义分段设置分段数量 绘制世界地图总结 地理空间数据可视化 地理空间数据可视化涉及将含有地理定位信息的数据转换成图形或影像形式&#xff0c;以此增强数据的理解与解析。这一方法广泛应用于诸如都市策划、生态守…

一文详解大模型推理:从基础知识到 vLLM

推理 本章正在建设中 - 一些部分已经完成&#xff0c;一些刚刚开始&#xff0c;还有许多尚未开始&#xff0c;但已经有足够多的有用部分完成&#xff0c;使其值得阅读。 术语表 CLA: 跨层注意力&#xff08;Cross-Layer Attention&#xff09;FHE: 全同态加密&#xff08;Fu…

【语音转文本新体验】Windows部署Whisper Web结合内网穿透轻松远程转录——“cpolar内网穿透”

文章目录 前言1.本地部署Whisper Web1.1 安装git1.2 安装Node.js1.3 运行项目 2. Whisper Web使用介绍3. 安装Cpolar内网穿透4. 配置公网地址5. 公网访问测试6. 配置固定公网地址 前言 OpenAI开源的 Whisper 语音转文本模型效果都说还不错&#xff0c;今天就给大家推荐 GitHub…

深入理解HTTPS协议原理

目录 加密 对称加密 非对称加密 中间人攻击 证书 验证证书合法性 HTTPS工作原理 常见问题 HTTPS即安全超文本传输协议&#xff0c;是互联网上进行安全通信的一种重要协议。它是在HTTP的基础上增加了安全性的要求&#xff0c;通过SSL或TLS协议对数据进行加密&#xff0c…

省、市、县夜间灯光数据大全(Excel+shp数据)(1992-2022年)

夜间灯光数据&#xff0c;作为一种遥感数据&#xff0c;能够为我们揭示夜晚地球的灯光和火光分布情况。这种数据不仅能够反映人类活动的空间分布&#xff0c;还能作为经济发展、社会进步和环境变化的一个量化指标。通过分析夜间灯光的亮度和分布&#xff0c;我们可以对一个地区…

Spring三级缓存解决循环依赖?构造方法的循环依赖问题解决(原理、详细过程、面试题)

目录 1.什么是循环依赖 2.Spring三级缓存介绍 3.二级缓存可以解决循环依赖吗&#xff1f; 3.1 二级缓存解决循环依赖过程详解 4. 为什么还需要三级缓存呢&#xff1f;/Spring三级缓存的作用&#xff1f; 4.1三级缓存解决循环依赖过程详解 4.2 为什么二级缓存就不能解决代…