小程序中封装下拉选择框

news2024/9/21 22:56:41

小程序中没有现成的下拉选择组件,有个picker组件,但是是底部弹出的,不满足我的需求,所以重新封装了一个。

封装的下拉组件

html部分:

<view class="select_all_view">
  <!-- 内容说明,可以没有 -->
  <view class="select_title" wx:if="{{title}}">{{title}}</view>
  <view class="select_view" style="width: {{selectWidth}};">
    <!-- 输入框 -->
    <view class="inputPlaceholder" bindtap="startChange">
      <text class="text" wx:if='{{select}}'>{{select}}</text>
      <text class="text placeholder_text" wx:else="{{select}}">{{placeholder}}</text>
      <view class="drop_down" wx:if='{{changable}}'>
        <image style="width:48rpx;height:48rpx" src="../../image/drop_up.png" mode="" />
      </view>
      <view class="drop_down" wx:else='{{changable}}'>
        <image style="width:48rpx;height:48rpx" src="../../image/drop_down2.png" mode="" />
      </view>
    </view>
    <!-- 下拉展开后的可选择内容 -->
    <view class="content" wx:if='{{changable}}'>
      <view class="select_item {{item.id==selectId ? 'active':''}}" wx:for="{{selectcontent}}" wx:key="idnex" bindtap="changecontent" data-datavalue="{{item}}">
        {{item.name}}
      </view>
    </view>
  </view>
</view>

css部分:

.select_all_view {
  display: flex;
  z-index: 999;
}

.select_view {
  display: inline;
  position: relative;
}

.inputPlaceholder {
  width: 100%;
  height: 64rpx;
  border: 2rpx solid #3A3A3A;
  font-size: 28rpx;
  line-height: 32rpx;
  color: #D8D4D4;
  border-radius: 12rpx;
  padding-left: 30rpx;
  box-sizing: border-box;
  position: relative;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.select_view .inputPlaceholder .text {
  line-height:64rpx;
}

.placeholder_text {
  color: #9B9B9B;
  font-size: 28rpx;
}

.drop_down {
  position: absolute;
  right: 12rpx;
  top: 8rpx;
}

.content {
  width: 100%;
  background: #FFFFFF;
  color: #505050;
  font-size: 30rpx;
  box-shadow: 0 0 12rpx 2rpx rgba(0, 0, 0, 0.38);
  border-radius: 16rpx;
  padding: 10rpx 12rpx;
  box-sizing: border-box;
  position: absolute;
  top: 76rpx;
  z-index: 999;
}

.select_item {
  width: 100%;
  height: 76rpx;
  display: flex;
  justify-content: center;
  align-items: center;
}

.select_view .content .active {
  background: #EDF5FF;
  border-radius: 4rpx;
  color: #1061FE;
}

js部分:

Component({
  properties: {
    selectWidth: {
      type: String,
      value: '100%'
    },
    title: {
      type: String,
      value: ""
    },
    nameList: {
      type: Array,
      value: [],
      observer: function () {
        //有的时候选项组是后端获取数据来的,初始化时可能为[],所以这里使用obersver,当父组件中值改变时触发
        this.processData();
      }
    },
    nowId: {
      type: Number,
      value: -1
    },
    nowName: {
      type: String,
      value: "",
      observer: function () {
        this.setData({
          select: this.properties.nowName,
          selectId: this.properties.nowId,
        });
      }
    },
    placeholder: {
      type: String,
      value: ""
    }
  },

  /**
   * 页面的初始数据
   */
  data: {
    selectcontent: [],
    changable: false, //箭头切换
    select: undefined, //选中的值
    selectId: undefined, //选中的id
  },
  methods: {
    // 下拉框收起和展开
    startChange(e) {
      this.setData({
        changable: !this.data.changable
      })
    },
    // 选择数据后回显
    changecontent(e) {
      this.setData({
        select: e.currentTarget.dataset.datavalue.name,
        selectId: e.currentTarget.dataset.datavalue.id,
        changable: false
      })
      this.triggerEvent("handleChange", { item: e.currentTarget.dataset.datavalue });//向父组件传参
    },
    //处理数据,复制一遍,因为子组件不能直接改变父组件的传进来的值。
    processData() {
      this.setData({
        selectcontent: this.properties.nameList,
        select: this.properties.nowName,
        selectId: this.properties.nowId,
      });
    },
    // 关闭下拉框
    closeSelect() {
      this.setData({
        changable: false
      });
    }
  }
})

在父组件中使用:

HTML部分:

<view class="dropdown_box">
  <dropdown style="margin-right: 20rpx;" class="dropdown" id="dropdown1" selectWidth="240rpx" nowId="{{firstTitleId}}" nameList="{{firstTitle}}" placeholder="请选择" nowName="{{firstTitleVal}}" bind:handleChange="changeFirstTitle"></dropdown>
  <dropdown class="dropdown" id="dropdown2" selectWidth="240rpx" nowId="{{secondTitleId}}" nameList="{{secondTitle}}" nowName="{{secondTitleVal}}" placeholder="请选择" bind:handleChange="changeSecondTitle"></dropdown>
  <dropdown class="dropdown" id="dropdown3" nowId="{{wordLimitId}}" nameList="{{wordLimitList}}" nowName="{{wordLimitVal}}" placeholder="请选择字数" bind:handleChange="changeWords"></dropdown>
</view>

。json文件:

{
  "usingComponents": {
    "dropdown":"../component/dropdown/dropdown"
  }
}

js部分:

Page({

  /**
   * 页面的初始数据
   */
  data: {
    firstTitle: [
      {
        id: 1,
        name: '标题创作'
      },
      {
        id: 2,
        name: '社媒文案'
      },
      {
        id: 3,
        name: '故事创作'
      },
    ],
    secondTitle: [],  //二级标题数组
    wordLimitList: [
      {
        id: 1,
        name: '不限',
        value: 800
      },
      {
        id: 2,
        name: '约150字≈30s',
        value: 150
      },
      {
        id: 3,
        name: '约300字≈60s',
        value: 300
      },
      {
        id: 4,
        name: '约600字≈120s',
        value: 600
      },
    ],
    firstTitleVal: "社媒文案",
    firstTitleId: 2,
    secondTitleVal: "文章改写",
    secondTitleId: 4,
    wordLimitVal: "",
    wordLimitId: 1
  },

  /**
   * 生命周期函数--监听页面加载
   */
  onLoad(options) {
  },
  // 选择一级标题
  changeFirstTitle(e) {
    let selectId = e.detail.item.id
  },
  // 选择二级标题
  changeSecondTitle(e) {
    console.log(e)
  },
  // 选择字数
  changeWords(e) {
  },
  //点击当前选择框时,关闭其他下拉弹出框;点击页面其他部分,关闭所有下拉弹出框
  handlePageTap(e) {
    const dropdownIds = ['dropdown1', 'dropdown2', 'dropdown3'];
    const clickedId = e.target.id;
    if (dropdownIds.includes(clickedId)) {
      const otherDropdownIds = dropdownIds.filter(id => id !== clickedId);
      otherDropdownIds.forEach(id => {
        const dropdown = this.selectComponent('#' + id);
        dropdown.closeSelect();
      });
    } else {
      const dropdowns = this.selectAllComponents('.dropdown');
      dropdowns.forEach(dropdown => {
        dropdown.closeSelect();
      });
    }
  },
})

页面效果图:
在这里插入图片描述

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

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

相关文章

ref和reactive, toRefs的使用

看尤雨溪说&#xff1a;为什么Vue3 中应该使用 Ref 而不是 Reactive&#xff1f; toRefs import { ref, toRefs } from vue;// 定义一个响应式对象 const state ref({count: 0,name: Vue });// 使用toRefs转换为响应式引用对象 const reactiveState toRefs(state);// 现在你…

vue3 之 组合式API—reactive和ref函数

ref&#xff08;&#xff09; 作用&#xff1a;接收简单类型或者对象类型的数据传入并返回一个响应式的对象 核心步骤&#xff1a; 1️⃣ 从 vue 包中导入 ref 函数 2️⃣在 <script setup>// 导入import { ref } from vue// 执行函数 传入参数 变量接收const count …

2024亿级密码泄露事件:涉及7084万个邮箱账号

近日&#xff0c;热门漏洞通知服务HIBP所有者特洛伊・亨特&#xff08;Troy Hunt&#xff09;发布博文&#xff0c;表示在暗网上发现了超大规模的泄漏数据集&#xff0c;被称为Naz.API列表。该数据集包含7084万个电子邮件地址以及超过1亿个密码凭证&#xff0c;至少有超过40万 …

【AG32VF407】国产MCU+FPGA Verilog双边沿检测输出方波

视频讲解 [AG32VF407]国产MCUFPGA Verilog双边沿检测输出方波 实验过程 本次使用使用AG32VF407开发板中的FPGA&#xff0c;使用双clk的双边沿进行检测&#xff0c;同步输出方波 同时可以根据输出的方波检测clk的频率&#xff0c;以及双clk的相位关系&#xff0c;如下为verilog…

Google play全球桌面棋牌游戏下载量周排行榜(2024.01.22—01.28)

今天酷鸟远程整理了Google paly桌面棋牌类游戏在美国、香港、巴西地区下载量排行榜前20名情况。 作为谷歌开发者的你&#xff0c;快来看看有没有你关心的游戏应用吧。 如果还想看更多或其它国家和地区的应用&#xff0c;或其它类别应用的相关具体数据&#xff0c;例如&#x…

Patch2QL:开源供应链漏洞挖掘和检测的新方向

背景 开源生态的上下游中&#xff0c;漏洞可能存在多种成因有渊源的其它缺陷&#xff0c;统称为“同源漏洞”&#xff0c;典型如&#xff1a; 上游代码复用缺陷。开源贡献者在实现功能相似的模块时&#xff0c;常复用已有模块代码或逻辑&#xff1b;当其中某个模块发现漏洞后…

成都爱尔林江院长解读儿童青少年为什么一定要进行医学验光配镜

根据国家卫健委数据显示&#xff1a;我国青少年儿童总体近视率为52.7%、高度近视人口超3000万。近视学生中,有10%为高度近视,且占比随年级升高而增长。 近视孩子之多&#xff0c;孩子视力发展备受关注。戴镜进行近视防控十分必要&#xff0c;且眼镜不可随意验配&#xff01; 成…

2024年【安全员-B证】考试资料及安全员-B证模拟考试题库

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 2024年安全员-B证考试资料为正在备考安全员-B证操作证的学员准备的理论考试专题&#xff0c;每个月更新的安全员-B证模拟考试题库祝您顺利通过安全员-B证考试。 1、【多选题】《中华人民共和国安全生产法》规定&#…

Linux下qemu的安装并搭建虚拟arm环境(带helloworld测试)【超详细】

qemu的安装并搭建虚拟arm环境 1、准备工作1.1 安装交叉汇编工具1.2 编译内核kernel1.3 u-boot编译1.4 制作根文件系统-busybox 2、启动qemu&#xff08;arm&#xff09;3、helloworld测试 1、准备工作 1.1 安装交叉汇编工具 交叉编译器的作用就不需要详细解释了&#xff0c;因…

C++ Primer 8.1 IO类 知识点

C Primer 8.1 IO类 io对象无拷贝赋值条件状态管理缓存练习题 io对象无拷贝赋值 ofstream out1,out2; //以下操作全为错误 out1out2; ofstream print(out2); out2print(out1)&#xff1b;条件状态 流对象的rdstate成员返回一个iostate值&#xff0c;表示其状态(P279) aotu ol…

springboot151基于web的人力资源管理系统的设计与实现

人力资源管理系统的设计与实现 摘 要 传统信息的管理大部分依赖于管理人员的手工登记与管理&#xff0c;然而&#xff0c;随着近些年信息技术的迅猛发展&#xff0c;让许多比较老套的信息管理模式进行了更新迭代&#xff0c;员工信息因为其管理内容繁杂&#xff0c;管理数量繁…

六大免费的Redis内存分析工具

在我们需要分析Redis实例的内存使用情况时&#xff0c;市场上有着许多免费的开源工具&#xff0c;同时也有少量的付费产品。如果您想更深层次地分析内存相关问题的话&#xff0c;就可能需要用到一些更具针对性的“独门”工具了。 【51CTO.com快译】在我们需要分析Redis实例的内…

STM32--HAL库定时器学习记录(易懂)--持续学习

一、什么是定时器 定时器就是计数器&#xff0c;通过计数完成一系列功能。 二、定时器的分类 定时器分为基本定时器、通用定时器、高级定时器。级别不同&#xff0c;功能不同。级别越高&#xff0c;功能越强。 三、定时器&#xff08;计数器&#xff09;三个重要寄存器 预分…

机器学习_15_贝叶斯算法

文章目录 1 贝叶斯定理相关公式2 朴素贝叶斯算法2.1 朴素贝叶斯算法推导2.2 朴素贝叶斯算法流程 3 高斯朴素贝叶斯4 伯努利朴素贝叶斯5 多项式朴素贝叶斯6 贝叶斯网络6.1 最简单的一个贝叶斯网络6.2 全连接贝叶斯网络6.3 “正常”贝叶斯网络6.4 实际贝叶斯网络&#xff1a;判断…

中国城乡建设统计年鉴,pdf、xls格式,时间覆盖2002-2022年

基本信息&#xff1a; 数据名称: 中国城乡&#xff08;市&#xff09;建设统计年鉴 数据格式: pdf、xls不定 数据时间: 2002-2022年 数据几何类型: 文本 数据坐标系: —— 数据来源&#xff1a;住房和城乡建设部 2005年之后数据中有《中国城市建设统计年鉴》、《中…

基于JAVA的宠物管理系统

技术架构&#xff1a; Servlet JSP MySQL 有需要该项目的小伙伴可以私信我你的Q。 功能介绍&#xff1a; 系统主要分为前台和后台两大模块 前台主要由用户体验使用: 用户登录 注册 查找商品 商品类别等功能导航&#xff1b; 后台…

一些你可能用到的函数和头文件

不知道大家对于bool&#xff08;布尔&#xff09;函数记忆如何&#xff0c;今天我们就讲一下 bool 函数。 在一些要判断一个数是否具有某种性质的时候可以使用 bool 函数&#xff0c;在一些情况下可以结合使用if else 或 switch 以及 while 等函数来做到判断性质。 1. bool 函…

雨云免费SSL证书介绍

SSL证书是网站保护用户数据安全和保护网站自身免受黑客攻击的有效工具。雨云免费SSL证书是一种免费的SSL证书服务。 什么是SSL证书&#xff1f; SSL&#xff08;Secure Sockets Layer&#xff09;证书是一个数字证书&#xff0c;可以证明网站身份的真实性&#xff0c;并保护在…

【Java程序设计】【C00246】基于Springboot的留守儿童爱心网站(有论文)

基于Springboot的留守儿童爱心网站&#xff08;有论文&#xff09; 项目简介项目获取开发环境项目技术运行截图 项目简介 这是一个基于Springboot的留守儿童爱心网站 本系统分为系统功能模块、管理员功能模块以及用户功能模块。 系统功能模块&#xff1a;系统首页的主要功能展…

【C++】使用g++指令控制【翻译】各个过程

前言 大家好吖&#xff0c;欢迎来到 YY 滴 系列 &#xff0c;热烈欢迎&#xff01; 本章主要内容面向接触过C的老铁 主要内容含&#xff1a; 欢迎订阅 YY滴C专栏&#xff01;更多干货持续更新&#xff01;以下是传送门&#xff01; YY的《C》专栏YY的《C11》专栏YY的《Linux》…