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

这篇具有很好参考价值的文章主要介绍了uni-app微信小程序开发自定义select下拉多选内容篇。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

欢迎点击领取 -《前端开发面试题进阶秘籍》:前端登顶之巅-最全面的前端知识点梳理总结

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

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

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

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说明文档在文章底部文章来源地址https://www.toymoban.com/news/detail-638000.html

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

到了这里,关于uni-app微信小程序开发自定义select下拉多选内容篇的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • uni-app+vue3+vite+微信小程序开发的问题点

    目录名称不能为api,否则会出现 ├F10: PM┤ [vite] getaddrinfo ENOTFOUND rivtrust.jz-xxx.xyz ,修改为_api; vue3的全局变量挂载 或者 全局变量的引入: 或者 axios在微信小程序上使用的问题: 安装模块 出现adapter is not a function的解决方法 需要axios自定义适配器配置 整体代码request.js: un

    2024年02月13日
    浏览(80)
  • Uni-App 中使用微信小程序开发,你可以通过以下步骤来设置节点属性

    在 Uni-App 中使用微信小程序开发,你可以通过以下步骤来设置节点属性: 在模板中定义节点:在 wxml 文件中,使用标签定义要操作的节点,并为它添加一个唯一的 id 属性,例如:   在 js 文件中获取节点的引用:使用  uni.createSelectorQuery()  方法创建选择器查询对象,并使用

    2024年02月15日
    浏览(44)
  • uni-app启动小程序篇(字节,微信)

    uni-app启动小程序篇 uni-app在字节工具小程序启动 1.1 在Hbuild X点击运行, 进入运行设置 1.2 进入运行设置后,设置字节小程序的运行位置   1.3 以上配置完成后,点击运行到小程序   1.4 启动成功后 复制该地址   1.5 打开字节小程序,选小程序,点击新建   1.6 进入后点击导入项目,将刚

    2024年02月11日
    浏览(46)
  • uni-app 微信小程序端-AirKiss一键配网

    发现网上很多关于微信小程序配网的文章都是微信小程序原生开发,uni-app少之又少。这篇文章就介绍一下怎么在HBuilder X使用airkiss配网插件。 一.AirKiss介绍 ​ AirKiss是微信硬件平台为Wi-Fi设备提供的微信配网、局域网发现和局域网通讯的技术。开发者若要实现通过微信客户端

    2024年02月08日
    浏览(51)
  • uni-app +java小程序端对接微信登陆

    要想实现微信登陆,首先必须注册开发者账号。 登录微信开放平台,添加移动应用并提交审核,审核通过后可获取应用ID(AppID),AppSecret等信息 在应用详情中 申请开通 微信登录功能,根据页面提示填写资料,提交审核 申请审核通过后即可打包使用微信授权登录功能 1.app端

    2024年02月11日
    浏览(46)
  • uni-app 支持 app端, h5端,微信小程序端 图片转换文件格式 和 base64

    uni-app 支持 app端 h5端,微信小程序端 图片转换文件格式 和 base64,下方是插件市场的地址 app端 h5端,微信小程序端 图片转换文件格式 和 base64 - DCloud 插件市场 https://ext.dcloud.net.cn/plugin?id=13926

    2024年02月13日
    浏览(68)
  • uni-app移动端-H5-微信小程序下载保存图片,文档和视频到手机,带进度条

    可移步插件地址,可直接导入hbuilderx示例项目查看: uni-app移动端-H5-微信小程序下载保存图片,文档和视频到手机,带进度条 具体代码如下

    2024年02月13日
    浏览(39)
  • uni-app 微信小程序自定义导航栏

    上面的导航栏主要由状态栏(就是手机电量显示栏)和小程序的导航栏组成,android手机一般为48px,ios手机一般为44px 1、设置navigationStyle:custom 2、页面导航栏div 3、获取statusBarHeight高度 4、获取navTitleHeight的高度

    2024年02月14日
    浏览(63)
  • uni-app微信小程序,APP都适用自定义顶部导航

    *使用自定义的导航样式,首先需要把原生的顶部的导航方式给隐藏掉(\\\"navigationStyle\\\": \\\"custom\\\") *手机顶部手机状态栏的高度 *微信小程序中胶囊的位置信息存储(使用store存储) *由于微信小程序中带有导航胶囊,所以需要根据胶囊去获取一定的参数信息 在微信小程序中,我们只需要获

    2024年02月06日
    浏览(64)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包