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

news2024/11/16 17:55:27

分享-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>
      <img
        class="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-checkbox
                mode="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.coloradmin.cn/o/853270.html

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

相关文章

浏览器多管闲事之跨域

年少时的梦想就是买一台小霸王游戏机 当时的宣传语就是小霸王其乐无穷~。 大些了&#xff0c;攒够了零花钱&#xff0c;在家长的带领下终于买到了 那一刻我感觉就是最幸福的人 风都是甜的&#xff01; 哪成想... 刚到家就被家长扣下了 “”禁止未成年人玩游戏机 (问过卖家了&a…

AWS中Lambda集成SNS

1.创建Lambda 在Lambda中&#xff0c;创建名为AWSSNSDemo的函数 use strict console.log(loading function); var aws require(aws-sdk); var docClient new aws.DynamoDB.DocumentClient(); aws.config.regionap-southeast-1;exports.handler function(event,context,cal…

C语言实现选择排序

什么是选择排序&#xff1f; 选择排序是一种简单直观的排序算法&#xff0c;它的核心思想是每次从未排序的元素中选择最小&#xff08;或最大&#xff09;的元素&#xff0c;然后将其放到已排序序列的末尾。通过重复这个过程&#xff0c;直到所有元素都排好序为止。 选择排序…

IntelliJ IDEA如何重新弹出git身份验证窗口

1、点击File菜单—>点击Settings—>点击Appearance & Behavior—>点击System Settings—>点击Passwords—>选中Do not save, forget passwords after restart—>点击Apply—>点击OK&#xff0c;如下所示&#xff1a; 2、重启IntelliJ IDEA—>通过g…

idea集成svn

一、注意 安装svn客户端的时候一定要勾选&#xff0c;否则在idea上集成svn的时候会找不到 svn.exe 而报错。 如果当初安装时忘记勾选&#xff0c;重新运行安装包&#xff0c;选择modify&#xff0c;勾选command line client tools项中的内容。 二、配置idea集成svn 三、检出(c…

生产车间SOP+电子作业指导书系统解决方案

为了提高生产效率&#xff0c;许多企业开始使用SOP电子作业指导书系统来统一管理和快速发布工作指导书。这种系统不仅能够实现无纸化办公&#xff0c;节省企业资源&#xff0c;还能集成生产管理看板系统和安灯呼叫系统&#xff0c;实现生产现场数据的目视化管理。 一、SOP系统拓…

简单数据类型

目录 前言 一.变量 1.1 变量命名 2.1 变量定义 二.类型 2.1 字符串 2.1.1 定义 2.1.2 操作 2.1.3 python2中的print语句 2.2 整数 2.2.1 运算 2.2.2 浮点数 2.2.3 str()函数 2.3 列表 2.3.1 访问和使用列表元素 2.3.2 在列表中添加元素 2.3.3 从列表中删除元素 2.3.4 组织列表…

LangChain源码逐行解密之LLMs(二)

LangChain源码逐行解密之LLMs(二) 18.3 base.py源码逐行剖析 现在我们要聚焦于源代码中的大语言模型部分。如图18-3所示,LangChain提供了许多语言模型的选择。 Gavin大咖微信:NLP_Matrix_Space 图18- 3 LangChain的llms目录 如图18-4所示,整个LangChain的模块化设计非常出…

最小花费 c++详解

最小花费 c详解 最小花费题目描述输入格式输出格式样例样例输入样例输出 提示 解法代码 最小花费 题目描述 在 n n n 个人中&#xff0c;某些人的银行账号之间可以互相转账。这些人之间转账的手续费各不相同。给定这些人之间转账时需要从转账金额里扣除百分之几的手续费&…

如何实现电子合同管理系统与其他企业应用的无缝对接?

电子合同管理系统是一种利用信息技术来管理和执行合同的系统。随着企业数字化转型的推进&#xff0c;电子合同管理系统已经成为许多企业必备的工具之一。然而&#xff0c;要实现电子合同管理系统与其他企业应用的无缝对接&#xff0c;并不是一件容易的事情。 实现电子合同管理…

深度解读|一站式ABI平台 Smartbi Insight V11 能力再升级

纵观过去&#xff0c;我们发现汽车和BI的发展有异曲同工之妙。 100来年&#xff0c;汽车的动力从蒸汽到燃油再到新能源&#xff0c;汽车的操控方式从手动到自动再到智能无人驾驶。而在BI领域&#xff0c;自1958年BI的概念提出后&#xff0c;底层数据准备从报表开发、Cube多维模…

图像的缩放之c++实现(qt + 不调包)

1.基本原理 图像的缩放一般使用插值算法&#xff0c;而本章将介绍两种常用插值算法&#xff1a;最临近插值法和双线性插值法 1.最临近插值法 将浮点数的位置坐标&#xff0c;进行四舍五入找到原图像的整型坐标即可&#xff0c;具体操作可见下面的公式&#xff0c;其中原图像坐标…

MES系统在机器人行业生产管理种的运用

机器人的智能水平也伴随技术的迭代不断攀升。 2021年的春晚舞台上&#xff0c;来自全球领先工业机器人企业abb的全球首款双臂协作机器人yumi&#xff0c;轻松自如地表演了一出写“福”字&#xff0c;赢得了全国观众的赞叹。 在汽车装配领域&#xff0c;一台机器人可以自主完成一…

【笔记】线段树

【笔记】线段树 目录 简介定义建树更新例题1: 单点修改&#xff0c;区间查询单点修改区间查询本题完整代码 例题2: 区间修改&#xff0c;单点查询思路本题完整代码 例题3: 区间修改&#xff0c;区间查询懒标记基本思想应用 区间修改本题完整代码 简介 线段树是一棵二叉树。如果…

带团队后的日常思考

一、日常问题 1&#xff09;补充产品文档 最近版本迭代&#xff0c;其中涉及一块举报流程的优化&#xff0c;其实会涉及管理后台发送站内信。 刚开始&#xff0c;大家都没怎么在意这个需求&#xff0c;但是在执行时才发现有许多细节没有考虑到。 管理后台的举报页面是在 2018 …

【C++技能树】一文看懂模板匹配

Halo&#xff0c;这里是Ppeua。平时主要更新C&#xff0c;数据结构算法&#xff0c;Linux与ROS…感兴趣就关注我bua&#xff01; 文章目录 0.泛型编程1.模板2 函数模板:2.1函数模板的特化 3. 类模板3.1 非类型模板参数3.2 类的模板刻画3.2.1 全特化3.2.2 偏特化 0.泛型编程 假…

在Microsoft SQL Server 2008中,语法生成错误“并行数据仓库(PDW)功能未启用“

案例&#xff1a; 原表有两列&#xff0c;分别为月份、月份销售额&#xff0c;而需要一条 SQL 语句实现统计出每个月份以及当前月以前月份销售额和 sql 测试数据准备&#xff1a; DECLARE Temp Table ( monthNo INT, --- 月份 MoneyData Float --- 金额 ) insert INTO TEM…

利用AIGC,零成本靠谱副业,每天半小时,挣个生活费不成问题,亲测,省时省力攻略

文章目录 背景为什么是写作如何操作申请各大创作平台的账号吸引人关注&#xff0c;增加粉丝利用AIGC来创作 看看其他好友分享的收入情况 背景 最近&#xff0c;尝试利用AIGC在头条号、微信公众号上开始写文章&#xff0c;并且通过这个机会赚取了一笔的外快。这个经历让我深刻认…

最强整理,HttpRunner接口自动化框架-hook机制实战,一篇上高速...

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 对于使用 Python结…

谷歌广告(Google ads)如何投放?新手必看的超全教程

Google是公认的全球最大的搜索引擎&#xff0c;同时&#xff0c;Google还通过旗下的 YouTube、Gmail、Google Play、Android等产品&#xff0c;汇集了海量的海外用户。对于跨境出海商家来说&#xff0c;谷歌广告是提高销售额、提高产品流量、拓展全球市场的重要推广渠道。 那么…