uni-app微信小程序开发自定义select下拉多选内容篇

分享-2023年资深前端进阶:前端登顶之巅-最全面的前端知识点梳理总结

*分享一个使用比较久的🪜

技术框架公司的选型:uni-app + uni-ui + vue3 + vite4 + ts

需求分析:微信小程序-uni-ui内容
1、创建一个自定义的下拉,支持多个内容的同时多选
2、定义好出入参数,支持回显内容等
3、绑定对应的v-model数据响应

在这里插入图片描述

1、代码信息
<template><view tabindex="1" ref="customSelectRef" class="uni-select" @click.stop="handleClickDiv"><view><template v-if="modelLabel.length"><span class="custom-tag" :key="index" v-for="(item, index) in modelLabel"><span>{{ item }}</span></span></template><span class="custom-tag" v-if="modelLabel.length && checkList.length - maxLength > 0">+ {{ checkList.length - maxLength }}</span><span v-if="!modelLabel.length" class="cus_placeholder">{{ placeholder }}</span><imgclass="icon-delete"v-if="modelLabel.length"@click.stop="handleRemove":src="'../../static/icons/delete.png'"/></view><transition><view class="cus_select_background" ref="cusSelectDropdown" v-if="isShowDropdown" @click="handleMemory"><view class="cus_tabs" :key="index" v-for="(item, index) in cusDataListChecked"><template v-if="item.children"><view class="cus_tabs_title">{{ item.text }}</view><view class="cus_tabs_body"><uni-data-checkboxmode="tag":multiple="multiple"v-model="item.checkList":localdata="item.children"@change="(val) => handleCheckedChange(val, item)"></uni-data-checkbox></view></template></view></view></transition><view v-if="isShowDropdown" class="custom_mask"></view></view>
</template><script setup lang="ts">
import { watch } from "vue";
import { toRaw } from "vue";
import { ref, onMounted, nextTick, onBeforeMount } from "vue";const props = withDefaults(defineProps<{dataSource: any;modelValue?: any;placeholder?: string;multiple?: boolean;maxLength?: number;}>(),{multiple: true,dataSource: [],modelValue: [],maxLength: 3,placeholder: "请选择",}
);const emit = defineEmits(["update:modelValue", 'change']);const customSelectRef = ref();const cusSelectDropdown = ref();const modelLabel = ref<Record<string, any>[]>([]);const checkList = ref<string[]>([]);const cusDataListChecked = ref<Record<string, any>[]>([]);const isShowDropdown = ref<boolean>(false);const isShowDownMemory = ref<boolean>(false);const handleClickDiv = () => {isShowDropdown.value = isShowDownMemory.value ? true : !isShowDropdown.value;isShowDownMemory.value = false;
};const handleMemory = () => {isShowDownMemory.value = true;
};const handleCheckedChange = (e: Record<string, any>, row: Record<string, any>) => {const { data } = e.detail;row.checkLabel = data.map((opt) => opt.text);getModelVal();
};const getModelVal = () => {const newValue = toRaw(cusDataListChecked.value);const newLabel = newValue.map((item) => item.checkLabel);const newModelVal = newValue.map((item) => item.checkList);const deconstructLabel = newLabel?.flat();const deconstructVal = newModelVal?.flat();modelLabel.value = deconstructLabel.slice(0, props.maxLength);checkList.value = deconstructVal;emit("update:modelValue", newModelVal);
};const handleRemove = (e) => {modelLabel.value = [];checkList.value = [];if (isShowDropdown.value) {isShowDropdown.value = false;}if (props.multiple) {cusDataListChecked.value = addCheckProperties(props.dataSource);}emit("update:modelValue", []);
};const addCheckProperties = (treeData) => {let result = [];result = JSON.parse(JSON.stringify(treeData));result.forEach((node) => {const child = node.children;node.checkList = [];node.checkLabel = [];if (child && child.length > 0) {addCheckProperties(child);}});return result;
};const findTreeChecked = (treeData) => {const newLabel = [];const val = toRaw(props.modelValue);treeData.forEach((node, index) => {if (node.children?.length) {const child = node.children;const bool = child.some((opt) => {const isExist = val[index] && val[index].includes(opt.value);isExist ? newLabel.push(opt.text) : void null;return isExist;});if (bool) {node.checkLabel = newLabel;node.checkList = val[index];}}});return treeData;
};watch(isShowDropdown, (newVal) => {emit('change', newVal, props.modelValue)
})onBeforeMount(() => {if (props.multiple) {cusDataListChecked.value = addCheckProperties(props.dataSource);}
});onMounted(async () => {await nextTick();if (props.multiple && props.modelValue.length) {cusDataListChecked.value = findTreeChecked(cusDataListChecked.value);getModelVal();}
});
</script><style lang="scss" scoped>
.uni-select {font-size: 14px;border: 1px solid #e5e5e5;box-sizing: border-box;border-radius: 4px;padding: 0 5px 0 10px;position: relative;display: flex;user-select: none;flex-direction: row;align-items: center;border-bottom: solid 1px #e5e5e5;width: 100%;flex: 1;height: 35px;position: relative;
}.cus_placeholder {color: #6a6a6a;font-size: 12px;
}.icon-delete {position: absolute;width: 18px;height: 18px;right: 5px;margin-top: 3.5px;z-index: 10;
}.cus_select_background {width: 95vw;max-height: 260px;box-sizing: border-box;border-radius: 4px;font-size: 13px;color: #606266;background: #ffffff;border: 1px solid #e4e7ed;position: absolute;top: 40px;left: 0px;padding: 5px 8px;z-index: 10;
}.cus_tabs {margin-bottom: 8px;.cus_tabs_title {font-weight: 600;margin-bottom: 4px;}.cus_tabs_body {margin-left: 12px;}
}.custom-tag {color: #909399;display: inline-flex;justify-content: center;align-items: center;height: 24px;padding: 0 9px;line-height: 1;border-radius: 4px;white-space: nowrap;font-size: 13px;margin-right: 5px;background-color: #f0f2f5;
}.custom_mask {position: fixed;top: 0;bottom: 0;left: 0;right: 0;z-index: 1;display: flex;justify-content: center;align-items: center;
}
</style>
2、使用api介绍

1、树形结构入参:dataSource=[{ ext: "服务器状态", children: [{ text: "在线", value: 0}]}]
2、标签引用:<ivuSelect :maxLength="2" ref="ivuSelectRef" v-model="customSelect" :dataSource="deviceDataList" style="width: 100%; margin-left: 5px" />
3、相关api说明文档在文章底部

参数说明类型默认值必填项
dataSource[{}]-label,value;树形结构Array[][]
modelValue当前选中项内容Array[]
placeholder输入框内容String请输入
multiple是否开启多选Booleanfalse
maxLength输入框最大标签长度Number3

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

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

相关文章

OSPF无法建立领居的原因有哪些(第三十五课)

1 配置OSPF 1.1 思路 1&#xff0c;配置IP地址 2&#xff0c;配置OSPF 配置进程号 route-id进入区域宣告网段 配置IP地址 R1路由表 ------------------------------------------------------------------------------ Routing Tables: Public Destinations : 10 …

《人脸识别技术应用安全管理规定(征求意见稿)》,需要关注三个焦点

目录 严防人脸信息采集与滥用 规范人脸识别信息的处理 保障人脸识别技术的安全 人脸识别主要有三类风险 近日&#xff0c;国家互联网信息办公室发布《人脸识别技术应用安全管理规定&#xff08;试行&#xff09;&#xff08;征求意见稿&#xff09;》公开征求意见的通知。 …

Python 模块 locust 性能测试

简介 locust 是 Python 的一个开源的负载测试工具&#xff0c;用于测试网络应用程序的性能和可伸缩性。它使用Python编写&#xff0c;并提供了一个简单易用的语法来定义和执行负载测试。locust模块允许用户模拟大量并发用户并观察系统在高负载下的响应情况。 目录 1. 基本用法…

多线程的实现方式Thread、Runnable、Callable

1.并发和并行 并发&#xff1a;在同一时刻&#xff0c;有多个指令在单个CPU上交替执行。 并行&#xff1a;在同一时刻&#xff0c;有多个指令在多个CPU上同时执行 2.多线程的实现方式 2.1 继承Thread类实现方式 2.2 实现Runnable接口的实现方式 2.3 利用Callable接口和Futur…

【网站收录前端需要怎么做?】

网站收录前端需要怎么做 什么是网站收录网站收录失败原因1. 网站被搜索引擎拉黑2. 网站结构不合理3. 网站内容质量差4. 网站没有被索引5. 网站新建时间太短 前端如何帮助提高网站收录 什么是网站收录 要想知道前端怎么做&#xff0c;首先我们来先了解一下这个收录是什么&#…

学习Helm来提高K8S运维效率

阶段一&#xff1a;了解 Helm 的基础知识和概念 Helm 简介&#xff1a; Helm 是 Kubernetes 的一个包管理工具&#xff0c;用于简化应用程序在 Kubernetes 上的部署和管理过程。它允许您使用预定义的模板&#xff08;Charts&#xff09;来描述应用程序的组件、依赖关系和配置…

基于金融行业的软件测试分析

随着银行业务不断增加&#xff0c;业务模式不断复杂化&#xff0c;对我们的银行软件也要求越来越高&#xff0c;产出高质量的产品也非常重要&#xff0c;下面对银行软件测试进行分析总结。 银行软件集中度高&#xff0c;规模庞大&#xff0c;往往是以系统群的方式存在&#xff…

F. Sum and Product - 思维

分析&#xff1a; 题目中的格式有点像韦达定理&#xff0c;就是对于一元二次方程ax^2 bx c 0有 所以可以推出要找的就是两个点&#xff0c;可以直接二分查找存不存在&#xff0c;这题有很多边界问题&#xff0c;有b^2 - 4ac小于0或者等于0&#xff0c;或者求出来的根在数组中…

【STM32】利用CubeMX对FreeRTOS用按键控制任务

对于FreeRTOS中的操作&#xff0c;最常用的就是创建、删除、暂停和恢复任务。 此次实验目标&#xff1a; 1.创建任务一&#xff1a;LED1每间隔1秒闪烁一次&#xff0c;并通过串口打印 2.创建任务二&#xff1a;LED2每间隔0.5秒闪烁一次&#xff0c;并通过串口打印 3.创建任…

创建型设计模式:5、原型模式(Prototype Pattern)

目录 1、原型模式的含义 2、C实现原型模式的简单实例 1、原型模式的含义 通过复制现有对象来创建新对象&#xff0c;而无需依赖于显式的构造函数或工厂方法&#xff0c;同时又能保证性能。 The prototype pattern is a creational design pattern in software development. …

Java算法_ 房子强盗(LeetCode_Hot100)

题目描述&#xff1a;你是一个专业的小偷&#xff0c;计划偷窃沿街的房屋。每间房内都藏有一定的现金&#xff0c;影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统&#xff0c;如果两间相邻的房屋在同一晚上被小偷闯入&#xff0c;系统会自动报警。 给定一个代表…

【字节跳动青训营】后端笔记整理-1 | Go语言入门指南:基础语法和常用特性解析

**本人是第六届字节跳动青训营&#xff08;后端组&#xff09;的成员。本文由博主本人整理自该营的日常学习实践&#xff0c;首发于稀土掘金&#xff1a;&#x1f517;Go语言入门指南&#xff1a;基础语法和常用特性解析 | 青训营 本文主要梳理自第六届字节跳动青训营&#xff…

【对于一维信号的匹配】对一个一维(时间)信号y使用自定义基B执行匹配追踪(MP)研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

【设计模式】-装饰器模式

Java 设计模式之装饰器模式 前言 在软件开发中&#xff0c;经常有需求对已有的对象进行功能的扩展&#xff0c;但是传统的继承方式会导致类的数量快速增多&#xff0c;且难以维护。为了解决这个问题&#xff0c;装饰器模式应运而生。 装饰器模式是一种结构型设计模式&#xff…

C++——关于命名空间

写c项目时&#xff0c;大家常用到的一句话就是&#xff1a; using namespace std; 怎么具体解析这句话呢&#xff1f; 命名冲突&#xff1a; 在c语言中&#xff0c;我们有变量的命名规范&#xff0c;如果一个变量名或者函数名和某个库里面自带的库函数或者某个关键字重名&…

深度优先搜索与动态规划|865, 1020, 1254

深度优先搜索|865. 具有所有最深节点的最小子树&#xff0c;1372. 二叉树中的最长交错路径&#xff0c;1631. 最小体力消耗路径 具有所有最深节点的最小子树二叉树中的最长交错路径最小体力消耗路径 具有所有最深节点的最小子树 一开始题没看懂&#xff0c;他这里就是找到最深…

python优雅地爬虫

申明&#xff1a;仅用作学习用途&#xff0c;不提供任何的商业价值。 背景 我需要获得新闻&#xff0c;然后tts&#xff0c;在每天上班的路上可以听一下。具体的方案后期我也会做一次分享。先看我喜欢的万能的老路&#xff1a;获得html内容-> python的工具库解析&#xff0…

Multimap用法详解

Multimap Multimap 是 Google 的 Guava 库为 Java 引入的一种新集合类型&#xff0c;它允许将多个值存储在单个键下。它被设计为一种替代 Map<K, List> 或 Map<K, Set>&#xff08;JDK 标准集合框架&#xff09;的方案。 Multimap<K, V> 扩展了 AbstractMul…

0基础学C#笔记09:希尔排序法

文章目录 前言一、希尔排序的思想二、使用步骤总结 前言 希尔排序可以说是插入排序的一种变种。无论是插入排序还是冒泡排序&#xff0c;如果数组的最大值刚好是在第一位&#xff0c;要将它挪到正确的位置就需要 n - 1 次移动。也就是说&#xff0c;原数组的一个元素如果距离它…

LeetCode--HOT100题(26)

目录 题目描述&#xff1a;142. 环形链表 II&#xff08;中等&#xff09;题目接口解题思路代码 PS: 题目描述&#xff1a;142. 环形链表 II&#xff08;中等&#xff09; 给定一个链表的头节点 head &#xff0c;返回链表开始入环的第一个节点。 如果链表无环&#xff0c;则返…