vue3+vite+uniapp 封装一个省市区组件

一、预览图

请添加图片描述

二、使用前的一些注意事项

  1. 只支持在 uniapp vue3 项目中使用
  2. 支持微信小程序和h5 (app端没有测试过)
  3. ui库用的 uview-plus
  4. 省市区数据用的是 vant-ui 提供的一个赖库 @vant/area-data

三、组件代码

<template><u-popup :show="show" type="bottom" @close="handlePopupClose" round="44rpx"><view class="area-picker"><view class="title">请选择收货地址<view class="close-icon" @click="handlePopupClose"><u-icon name="close" size="44rpx" color="#666666"></u-icon></view></view><view class="header"><view @click="doChange('province')":class="['header-item', activeType === 'province' ? 'header-item--active' : '']"v-if="activeType === 'province' || activeType === 'city' || activeType === 'district' || innerProvince">{{ innerProvince ? innerProvince.name : '请选择省' }}</view><view @click="doChange('city')" :class="['header-item', activeType === 'city' ? 'header-item--active' : '']"v-if="activeType === 'city' || activeType === 'district' || innerProvince">{{ innerProvince && innerCity ? innerCity.name : '请选择市' }}</view><view @click="doChange('district')":class="['header-item', activeType === 'district' ? 'header-item--active' : '']"v-if="activeType === 'district' || innerCity">{{ innerProvince && innerCity && innerCounty ? innerCounty.name : '请选择区' }}</view></view><scroll-view scroll-y class="main" :scroll-with-animation="true"><view :id="`tag-${item.id}`" :class="['main-item', select(item.name) ? 'main-item--active' : '']"@click="doSelect(item)" v-for="item in showList" :key="item.id"><u-icon v-if="select(item.name)" name="checkbox-mark" size="44rpx" color="#3c9cff"></u-icon>{{ item.name }}</view></scroll-view></view></u-popup>
</template>
<script setup>
import { computed, nextTick, ref } from 'vue'
import { areaList } from "@vant/area-data";const props = defineProps({show: {type: Boolean,default: false},area: {type: Array,default: () => []},id: {type: String,default: ''},
})const emits = defineEmits(['close', 'confirm']) // 事件const areaData = ref(areaList)let innerProvince = ref(null) // 选择的省
let innerCity = ref(null) // 选择的市
let innerCounty = ref(null) // 选择的区
let activeType = ref('province') // 当前所选的area类型
const viewId = ref(null) //  应当展示在视图中的节点id// 是否被选中
const select = computed(() => {return (item) => {switch (activeType.value) {case 'province':return innerProvince.value ? item === innerProvince.value.name : falsecase 'city':return innerCity.value ? item === innerCity.value.name : falsecase 'district':return innerCounty.value ? item === innerCounty.value.name : falsedefault:return innerProvince.value ? item === innerProvince.value.name : false}}
})// 展示的列表
const showList = computed(() => {switch (activeType.value) {case 'province':return provinceList.valuecase 'city':return cityList.valuecase 'district':return countyList.valuedefault:return provinceList.value}
})// 省列表
const provinceList = computed(() => {const provinceList = []if (areaData.value && areaData.value.province_list) {for (const key in areaData.value.province_list) {if (areaData.value.province_list[key]) {provinceList.push({id: key,name: areaData.value.province_list[key]})}}}return provinceList
})// 市列表
const cityList = computed(() => {const cityList = []if (areaData.value && areaData.value.city_list) {for (const key in areaData.value.city_list) {if (areaData.value.city_list[key] && innerProvince.value && innerProvince.value.id.slice(0, 2) === key.slice(0, 2)) {cityList.push({id: key,name: areaData.value.city_list[key]})}}}return cityList
})// 区列表
const countyList = computed(() => {const countyList = []if (areaData.value && areaData.value.county_list) {for (const key in areaData.value.county_list) {if (areaData.value.county_list[key] && (!innerProvince.value || (innerCity.value && innerCity.value.id.slice(0, 4) === key.slice(0, 4)))) {countyList.push({id: key,name: areaData.value.county_list[key]})}}}return countyList
})
// 关闭 popup 
function handlePopupClose() {emits('close')
}
// 地址选择完成
function doConfirm() {const list = [innerProvince.value, innerCity.value, innerCounty.value]const obj = {}list.forEach((v, i) => {i === 0 ? obj.province = v.name : ''i === 1 ? obj.city = v.name : ''i === 2 ? obj.county = v.name : ''});emits('confirm', obj, [innerProvince.value, innerCity.value, innerCounty.value])
}// 切换当前选择的省市区类型
function doChange(type) {activeType.value = type
}// 选中省市区项
function doSelect(item) {switch (activeType.value) {case 'province':if (innerProvince.value && innerProvince.value.id === item.id) {innerProvince.value = null} else {innerProvince.value = itemactiveType.value = 'city'}innerCity.value = nullinnerCounty.value = nullbreakcase 'city':if (innerCity.value && innerCity.value.id === item.id) {innerCity.value = null} else {innerCity.value = itemactiveType.value = 'district'}innerCounty.value = nullbreakcase 'district':if (innerCounty.value && innerCounty.value.id === item.id) {innerCounty.value = null} else {innerCounty.value = itemdoConfirm()}breakdefault:if (innerProvince.value && innerProvince.value.id === item.id) {innerProvince.value = null} else {innerProvince.value = itemactiveType.value = 'city'}innerCity.value = nullinnerCounty.value = nullbreak}
}
</script><style lang="scss" scoped>
$color-text-secondary: #101010;.area-picker {position: relative;height: 846rpx;height: calc(846rpx + constant(safe-area-inset-bottom));height: calc(846rpx + env(safe-area-inset-bottom));width: calc(100vw - 80rpx);background: #ffffff;padding: 0 40rpx;border-radius: 20rpx 20rpx 0px 0px;padding-bottom: 0;padding-bottom: constant(safe-area-inset-bottom);padding-bottom: env(safe-area-inset-bottom);.title {height: 114rpx;width: 100%;display: flex;align-items: center;justify-content: center;font-size: 36rpx;font-family: PingFangSC-Medium, PingFang SC;font-weight: 500;color: #202124;.close-icon {position: absolute;top: 57rpx;right: 0;padding: 19rpx;transform: translateY(-50%);}}.header {display: flex;margin-bottom: 24rpx;&-item {height: 44rpx;font-size: 32rpx;font-family: PingFangSC-Medium, PingFang SC;font-weight: 500;color: $color-text-secondary;max-width: 186rpx;white-space: nowrap;overflow: hidden;text-overflow: ellipsis;&:not(:last-child) {margin-right: 56rpx;}&--active {color: $u-primary;}}}.main {height: calc(100% - 182rpx);overflow: auto;::-webkit-scrollbar {width: 0;height: 0;color: transparent;}&-item {display: flex;align-items: center;white-space: nowrap;overflow: hidden;text-overflow: ellipsis;width: 100%;height: 84rpx;background: #ffffff;font-size: 28rpx;color: $color-text-secondary;image {width: 44rpx;height: 44rpx;}&--active {font-family: PingFangSC-Medium, PingFang SC;font-weight: 500;color: $color-text-secondary;}}}
}
</style>

四、组件使用

<template><view class="container"><u-button @click="show = true" type="primary" customStyle="width: 90%;margin-top: 60rpx;">选择区域</u-button><view style="text-align: center; margin-top: 60rpx;">所选区域:{{ areaText }}</view><AreaPicker :show="show" @confirm="handleConfirmArea" @close="show = false"></AreaPicker></view>
</template><script setup>
import { ref } from "vue";const show = ref(false);
const areaText = ref("");function handleConfirmArea(item) {console.log("当前选中区域:", item);const { province, city, county } = item;areaText.value = province + " " + city + " " + county;show.value = false;
}
</script><style lang="scss" scoped></style>

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

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

相关文章

iOS——仿写计算器

四则运算&#xff1a;中缀表达式转后缀表达式后缀表达式求值 实现四则运算的算法思路是&#xff1a;首先输入的是中缀表达式的字符串&#xff0c;然后将其转为计算机可以理解的后缀表达式&#xff0c;然后将后缀表达式求值&#xff1a; 中缀转后缀表达式思路参考&#xff1a;《…

现货白银图表分析的依据

现货白银的行情图表分析其实与股票的差不多&#xff0c;投资者可以结合均线、k线的变化&#xff0c;来分析实时的行情走势。当走势图的均线呈多头排列&#xff0c;即短期、中期、长期均线依次从上到下排列并向右上方运行&#xff0c;且白银价格沿各均线向右上方拉升&#xff0c…

数据产品读书笔记——认识数据产品经理

&#x1f33b;大家可能听说的更多是产品经理这个角色&#xff0c;对数据产品经理可能或多或少了解一些&#xff0c;但又不能准确的描述数据产品经理的主要职能和与其他产品的不同&#xff0c;因此通过读一些书来对数据产品经理有一个准确且全面的认知。 目录 1. 数据的产品分类…

基于生物地理学优化的BP神经网络(分类应用) - 附代码

基于生物地理学优化的BP神经网络&#xff08;分类应用&#xff09; - 附代码 文章目录 基于生物地理学优化的BP神经网络&#xff08;分类应用&#xff09; - 附代码1.鸢尾花iris数据介绍2.数据集整理3.生物地理学优化BP神经网络3.1 BP神经网络参数设置3.2 生物地理学算法应用 4…

Vue中如何进行图像识别与人脸对比(如百度AI、腾讯AI)

Vue中的图像识别与人脸对比 在现代Web应用程序中&#xff0c;图像识别和人脸对比技术越来越受欢迎。它们可以用于各种用途&#xff0c;如人脸识别门禁系统、图像分类和验证等。百度AI和腾讯AI是两个流行的人工智能平台&#xff0c;它们提供了强大的图像识别和人脸对比API。本文…

Sketch for mac v98.3(ui设计矢量绘图)

Sketch是一款为用户提供设计和创建数字界面的矢量编辑工具。它主要用于UI/UX设计师、产品经理和开发人员&#xff0c;帮助他们快速设计和原型各种应用程序和网站。 Sketch具有简洁直观的界面&#xff0c;以及丰富的功能集&#xff0c;使得用户可以轻松地创建、编辑和共享精美的…

【华为OD机考】统计监控、需要打开多少监控器(JAVA题解——也许是全网最优)

前言 本人是算法小白&#xff0c;甚至也没有做过Leetcode。所以&#xff0c;我相信【同为菜鸡的我更能理解作为菜鸡的你们的痛点】。 题干 OD&#xff0c;B 卷 100 分题目【OD 统一考试&#xff08;B 卷&#xff09;】 1. 题目描述 某长方形停车场每个车位上方都有一个监控…

Kafka快速实战以及基本原理详解

这一部分主要是接触 Kafka &#xff0c;并熟悉 Kafka 的使用方式。快速熟练的搭建 kafka 服务&#xff0c;对于快速验证一些基于Kafka 的解决方案&#xff0c;也是非常有用的。 一、 Kafka 介绍 ChatGPT 对于 Apache Kafka 的介绍&#xff1a; 1 、 MQ 的作用 MQ &#xff1a;…

网络原理 - 详解

一&#xff0c;网络通信基础 1.1 IP地址 描述一个设备在网络上的地址&#xff0c;一般使用4个0~255之间的数字&#xff0c;并且使用三给 . 进行分割&#xff0c;如&#xff1a;127.0.0.0 1.2 端口号 端口号是一个2个字节的整数&#xff0c;用来区分一个主机上的不同应用程序…

No168.精选前端面试题,享受每天的挑战和学习

🤍 前端开发工程师(主业)、技术博主(副业)、已过CET6 🍨 阿珊和她的猫_CSDN个人主页 🕠 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 🍚 蓝桥云课签约作者、已在蓝桥云课上架的前后端实战课程《Vue.js 和 Egg.js 开发企业级健康管理项目》、《带你从入…

Docker linux 安装

sudo yum update sudo yum clean all sudo yum makecache#安装依赖 sudo yum install -y yum-utils device-mapper-persistent-data lvm2 #添加官方存储库 sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo#安装-跳过一些异常依赖…

阿里云轻量应用服务器有月流量限制吗?

阿里云轻量应用服务器限制流量吗&#xff1f;部分限制&#xff0c;2核2G3M和2核4G4M这两款轻量应用服务器不限制月流量&#xff0c;其他的轻量服务器套餐有月流量限制。 腾讯云轻量应用服务器价格便宜&#xff0c;活动页面&#xff1a;aliyunbaike.com/go/tencent 细心的同学看…

HTML5+CSS3+移动web 前端开发入门笔记(二)HTML标签详解

HTML标签&#xff1a;排版标签 排版标签用于对网页内容进行布局和样式的调整。下面是对常见排版标签的详细介绍&#xff1a; <h1>: 定义一级标题&#xff0c;通常用于标题栏或页面主要内容的标题。<p>: 定义段落&#xff0c;用于将文字分段展示&#xff0c;段落之…

办公技巧:Excel日常高频使用技巧

目录 1. 快速求和&#xff1f;用 “Alt ” 2. 快速选定不连续的单元格 3. 改变数字格式 4. 一键展现所有公式 “CTRL ” 5. 双击实现快速应用函数 6. 快速增加或删除一列 7. 快速调整列宽 8. 双击格式刷 9. 在不同的工作表之间快速切换 10. 用F4锁定单元格 1. 快速求…

CSS学习笔记

目录 1.CSS简介1.什么是CSS2.为什么使用CSS3.CSS作用 2.基本用法1.CSS语法2.CSS应用方式1. 内部样式2.行内样式3.外部样式1.使用 link标签 链接外部样式文件2.import 指令 导入外部样式文件3.使用举例 3.选择器1.基础选择器1.标签选择器2.类选择器3.ID选择器4.使用举例 2.复杂选…

计算机视觉: 基于隐式BRDF自编码器的文生三维技术

论文链接: MATLABER: Material-Aware Text-to-3D via LAtent BRDF auto-EncodeR 背景 得益扩散模型和大量的text - image 成对的图片&#xff0c; 现在文生2D的模型已经比较成熟的框架和模型&#xff0c;主流的技术比如说stable diffusion 和 midjourney 以及工业领域runway 等…

ElasticSearch环境准备

Elasticsearch 是一个基于 Apache Lucene™ 的开源搜索引擎。不仅仅是一个全文搜索引擎&#xff0c;它还是一个分布式的搜索和分析引擎&#xff0c;可扩展并能够实时处理大数据。以下是关于 Elasticsearch 的一些主要特点和说明&#xff1a; 1.实时分析&#xff1a;Elasticsear…

反爬虫机制与反爬虫技术(一)

反爬虫机制与反爬虫技术一 1、网络爬虫的法律与道德问题2、反爬虫机制与反爬虫技术2.1、User-Agent伪装2.2、代理IP2.3、请求频率控制2.4、动态页面处理2.5、验证码识别3、反爬虫案例:豆瓣电影Top250爬取3.1、爬取目标3.2、库(模块)简介3.3、翻页分析3.4、发送请求3.5、数据…

【Solidity】智能合约案例——①食品溯源合约

目录 一、合约源码分析&#xff1a; 二、合约整体流程&#xff1a; 1.部署合约 2.管理角色 3.食品信息管理 4.食品溯源管理 一、合约源码分析&#xff1a; Producer.sol:生产者角色的管理合约&#xff0c;功能为&#xff1a;添加新的生产者地址、移除生产者地址、判断角色地址…

基于支持向量机SVM和MLP多层感知神经网络的数据预测matlab仿真

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 一、支持向量机&#xff08;SVM&#xff09; 二、多层感知器&#xff08;MLP&#xff09; 5.算法完整程序工程 1.算法运行效果图预览 2.算法运行软件版本 matlab2022a 3.部分核心程序 .…