更新记录

1.0.0(2026-04-09)

初始版本,实现多级联动选择(1-4级),支持智能搜索功能,弹窗式设计,响应式布局,性能优化


平台兼容性

uni-app(3.7.3)

Vue2 Vue3 Chrome Safari app-vue app-nvue Android iOS 鸿蒙
× - - - - -
微信小程序 支付宝小程序 抖音小程序 百度小程序 快手小程序 京东小程序 鸿蒙元服务 QQ小程序 飞书小程序 小红书小程序 快应用-华为 快应用-联盟
2.10.0 - - - - - - -

其他

多语言 暗黑模式 宽屏模式
× ×

多级联动选择器插件

带搜索功能的多级联动选择器弹窗,支持一级、二级、三级、四级联动选择,适用于地址选择、分类选择等多种场景。

功能特点

  • 多级联动选择:支持一级、二级、三级、四级联动选择,可根据需要灵活配置
  • 智能搜索功能:根据当前联动级别进行搜索,一级联动只搜索一级数据,二级联动搜索一级和二级数据,以此类推
  • 弹窗式设计:底部弹出的选择器,使用体验良好,不影响页面布局
  • 响应式布局:适配不同屏幕尺寸,在手机、平板等设备上均有良好表现
  • 支持uni-app:使用vue格式开发,兼容所有uni-app项目(包括H5、小程序、App等)
  • 数据结构清晰:返回的数据结构清晰明了,便于后续处理
  • 性能优化:动态加载数据,避免一次性加载过大的文件,提升性能
  • 用户友好:搜索结果自动高亮显示,选中状态清晰可见

应用场景

  • 地址选择:用户填写收货地址时,选择省市区街道
  • 分类选择:商品分类、行业分类等多级分类的选择
  • 地区筛选:根据地区筛选数据
  • 多级表单:需要多级联动的表单场景
  • 行政区划选择:政府、企业系统中需要选择行政区划的场景

安装方法

方式一:从插件市场安装

在uni-app插件市场搜索"多级联动选择器",找到本插件并点击"导入插件"。

方式二:手动安装

  1. 下载插件代码
  2. multi-level-linkage目录复制到项目的components目录下
  3. 在需要使用的页面中导入并注册组件

使用方法

基本使用

<template>
  <view>
    <view class="row">
      <view class="col">
        <!-- 一级联动 -->
        <view class="linkage-item">
          <view class="result-item">
            <view class="result-label">一级联动结果:</view>
            <view class="result-value">{{ level1Result }}</view>
          </view>
          <view class="btn" @click="openPicker(1)">一级联动</view>
        </view>

        <!-- 二级联动 -->
        <view class="linkage-item">
          <view class="result-item">
            <view class="result-label">二级联动结果:</view>
            <view class="result-value">{{ level2Result }}</view>
          </view>
          <view class="btn" @click="openPicker(2)">二级联动</view>
        </view>

        <!-- 三级联动 -->
        <view class="linkage-item">
          <view class="result-item">
            <view class="result-label">三级联动结果:</view>
            <view class="result-value">{{ level3Result }}</view>
          </view>
          <view class="btn" @click="openPicker(3)">三级联动</view>
        </view>

        <!-- 四级联动 -->
        <view class="linkage-item">
          <view class="result-item">
            <view class="result-label">四级联动结果:</view>
            <view class="result-value">{{ level4Result }}</view>
          </view>
          <view class="btn" @click="openPicker(4)">四级联动</view>
        </view>
      </view>
    </view>

    <!-- 多级联动组件 -->
    <MultiLevelLinkage 
      :show="showPicker" 
      :level="pickerLevel"
      @cancel="showPicker = false" 
      @confirm="handleConfirm"
    />
  </view>
</template>

<script setup>
import { ref } from 'vue';
import MultiLevelLinkage from '@/components/multi-level-linkage/multi-level-linkage.vue';

// 存储不同级别的联动结果
const level1Result = ref('');
const level2Result = ref('');
const level3Result = ref('');
const level4Result = ref('');

const showPicker = ref(false);
const pickerLevel = ref(3); // 默认三级联动
const currentLevel = ref(3); // 当前打开的联动级别

// 打开选择器
const openPicker = (level) => {
  pickerLevel.value = level;
  currentLevel.value = level;
  showPicker.value = true;
};

// 处理确认选择
const handleConfirm = (address) => {
  // 根据当前级别更新对应的结果
  if (currentLevel.value === 1) {
    level1Result.value = address.fullAddress;
  } else if (currentLevel.value === 2) {
    level2Result.value = address.fullAddress;
  } else if (currentLevel.value === 3) {
    level3Result.value = address.fullAddress;
  } else if (currentLevel.value === 4) {
    level4Result.value = address.fullAddress;
  }

  showPicker.value = false;
  console.log('选择的地址:', address);
};
</script>

<style scoped>
.row {
  width: 100%;
}

.col {
  display: flex;
  align-items: flex-start;
  flex-direction: column;
  padding: 30rpx;
  width: 100%;
  box-sizing: border-box;
  gap: 30rpx;
}

.linkage-item {
  width: 100%;
  display: flex;
  flex-direction: column;
  gap: 15rpx;
}

.result-item {
  width: 100%;
  padding: 15rpx;
  background-color: #f5f5f5;
  border-radius: 8rpx;
}

.result-label {
  font-size: 28rpx;
  color: #666;
  margin-bottom: 10rpx;
}

.result-value {
  font-size: 32rpx;
  color: #333;
  font-weight: 500;
}

.btn {
  padding: 20rpx 30rpx;
  background-color: #007aff;
  color: #fff;
  border-radius: 8rpx;
  font-size: 28rpx;
  font-weight: 500;
  transition: all 0.3s ease;
  text-align: center;
  box-sizing: border-box;
}

.btn:active {
  background-color: #0056b3;
}
</style>

自定义样式

如果需要自定义组件样式,可以通过以下方式:

  1. 在组件外部覆盖样式(使用 ::v-deep/deep/
  2. 修改组件内部的 CSS 样式

自定义数据

如果需要使用自定义的数据,可以修改组件中的 loadCitiesData 函数,从其他数据源加载数据。数据结构需要保持一致,即包含 codenamechildren 属性。

示例:

// 自定义数据结构
const customData = [
  {
    "code": "001",
    "name": "电子产品",
    "children": [
      {
        "code": "001001",
        "name": "手机",
        "children": [
          {
            "code": "001001001",
            "name": "苹果",
            "children": [
              { "code": "001001001001", "name": "iPhone 14" },
              { "code": "001001001002", "name": "iPhone 14 Pro" }
            ]
          },
          {
            "code": "001001002",
            "name": "华为",
            "children": [
              { "code": "001001002001", "name": "Mate 50" },
              { "code": "001001002002", "name": "P50" }
            ]
          }
        ]
      },
      {
        "code": "001002",
        "name": "电脑",
        "children": [
          {
            "code": "001002001",
            "name": "笔记本",
            "children": [
              { "code": "001002001001", "name": "MacBook Air" },
              { "code": "001002001002", "name": "MacBook Pro" }
            ]
          },
          {
            "code": "001002002",
            "name": "台式机",
            "children": [
              { "code": "001002002001", "name": "iMac" },
              { "code": "001002002002", "name": "Mac Studio" }
            ]
          }
        ]
      }
    ]
  }
];

// 修改 loadCitiesData 函数
const loadCitiesData = async () => {
  if (citiesData.value.length > 0) return;

  isLoading.value = true;
  try {
    // 使用自定义数据
    citiesData.value = customData;
  } catch (error) {
    console.error('Failed to load data:', error);
  } finally {
    isLoading.value = false;
  }
};

API

属性

属性 类型 默认值 说明
show Boolean false 控制选择器是否显示
level Number 3 联动级别,支持1-4级

事件

事件 说明 回调参数
cancel 取消选择
confirm 确认选择 地址对象,包含对应级别的属性和fullAddress属性

数据结构

确认选择时返回的地址对象结构

一级联动(仅省份):

{
  province: {
    code: "11",
    name: "北京市"
  },
  fullAddress: "北京市"
}

二级联动(省份+城市):

{
  province: {
    code: "11",
    name: "北京市"
  },
  city: {
    code: "1101",
    name: "市辖区"
  },
  fullAddress: "北京市 市辖区"
}

三级联动(省份+城市+区县):

{
  province: {
    code: "11",
    name: "北京市"
  },
  city: {
    code: "1101",
    name: "市辖区"
  },
  district: {
    code: "110101",
    name: "东城区"
  },
  fullAddress: "北京市 市辖区 东城区"
}

四级联动(省份+城市+区县+街道):

{
  province: {
    code: "11",
    name: "北京市"
  },
  city: {
    code: "1101",
    name: "市辖区"
  },
  district: {
    code: "110101",
    name: "东城区"
  },
  street: {
    code: "110101001",
    name: "东华门街道"
  },
  fullAddress: "北京市 市辖区 东城区 东华门街道"
}

城市数据

城市数据存储在pcas-code.json文件中,包含了全国各省市县街道的四级数据。数据结构如下:

[
  {
    "code": "11",
    "name": "北京市",
    "children": [
      {
        "code": "1101",
        "name": "市辖区",
        "children": [
          {
            "code": "110101",
            "name": "东城区",
            "children": [
              { "code": "110101001", "name": "东华门街道" },
              // 更多街道...
            ]
          },
          // 更多区县...
        ]
      },
      // 更多城市...
    ]
  },
  // 更多省份...
]

搜索功能说明

搜索功能会根据当前的联动级别进行智能搜索:

  • 一级联动:只搜索一级数据(如省份)
  • 二级联动:搜索一级和二级数据(如省份和城市)
  • 三级联动:搜索一级、二级和三级数据(如省份、城市和区县)
  • 四级联动:搜索一级、二级、三级和四级数据(如省份、城市、区县和街道)

搜索结果会自动高亮显示,并且会自动定位到对应的选项,方便用户快速选择。

性能优化

  1. 动态加载数据:使用 import() 动态加载数据文件,避免一次性加载过大的文件,提升页面加载速度
  2. 计算属性:使用 Vue 的计算属性缓存计算结果,减少重复计算
  3. 响应式数据:使用 Vue 的响应式数据,确保数据变化时页面能够及时更新
  4. 高效搜索算法:搜索功能使用了高效的遍历算法,确保搜索速度
  5. 按需渲染:根据当前联动级别按需渲染对应级别的选择器,减少 DOM 元素数量

常见问题

1. 如何修改数据来源?

如果需要使用自定义的数据,可以修改组件中的 loadCitiesData 函数,从其他数据源加载数据。数据结构需要保持一致,即包含 codenamechildren 属性。

2. 搜索功能如何工作?

搜索功能会根据当前的联动级别进行智能搜索,一级联动只搜索一级数据,二级联动搜索一级和二级数据,以此类推。搜索结果会高亮显示,并自动定位到对应的选项。

3. 如何优化性能?

  • 组件已经实现了动态加载数据,避免一次性加载过大的文件
  • 搜索功能使用了高效的遍历算法,确保搜索速度
  • 组件使用了 Vue 的计算属性和响应式数据,减少不必要的重渲染
  • 根据当前联动级别按需渲染对应级别的选择器,减少 DOM 元素数量

4. 支持哪些平台?

本插件支持所有 uni-app 支持的平台,包括:

  • H5
  • 微信小程序
  • 支付宝小程序
  • 百度小程序
  • 字节跳动小程序
  • QQ 小程序
  • App(iOS/Android)

5. 如何自定义样式?

可以通过以下方式自定义样式:

  • 在组件外部覆盖样式(使用 ::v-deep/deep/
  • 修改组件内部的 CSS 样式

6. 如何处理搜索结果为空的情况?

当搜索结果为空时,组件会显示所有一级数据,用户可以继续浏览和选择。

使用技巧

  1. 根据实际需求选择联动级别:根据实际业务需求选择合适的联动级别,避免不必要的层级
  2. 合理使用搜索功能:对于大量数据的场景,使用搜索功能可以快速定位目标选项
  3. 自定义数据结构:根据业务需求自定义数据结构,实现不同的联动场景
  4. 优化用户体验:根据用户的使用习惯,合理安排按钮和结果显示的布局
  5. 测试不同平台:在不同的平台上测试组件的表现,确保兼容性

版本更新

v1.0.0

  • 初始版本
  • 实现多级联动选择(1-4级)
  • 支持智能搜索功能
  • 弹窗式设计
  • 响应式布局
  • 性能优化

贡献

欢迎提交 Issue 和 Pull Request 来改进本插件。

许可证

本插件使用 MIT 许可证。

隐私、权限声明

1. 本插件需要申请的系统权限列表:

2. 本插件采集的数据、发送的服务器地址、以及数据用途说明:

插件不采集任何数据

3. 本插件是否包含广告,如包含需详细说明广告表达方式、展示频率:

暂无用户评论。