uniapp开发微信小程序底部地区选择弹框

news2025/1/11 5:44:05

个人项目地址: SubTopH前端开发个人站

(自己开发的前端功能和UI组件,一些有趣的小功能,感兴趣的伙伴可以访问,欢迎提出更好的想法,私信沟通,网站属于静态页面)

SubTopH前端开发个人站https://subtop.gitee.io/subtoph.github.io/#/home

以上 👆 是个人前端项目,欢迎提出您的建议😊

实现效果

功能介绍:

  1. 支持默认值直接显示滚动定位
  2. 选择上一次后,下一级重置请选择
  3. 选中样式可自定义
  4. 点击确认可校验省市县时候全部选择

 直接上代码模板部分(利用uniapp中的picker-view进一步封装)

<template>
  <view>
    <view
      class="tui-actionsheet-class tui-actionsheet"
      :class="[show ? 'tui-actionsheet-show' : '']"
    >
      <view class="regional-selection">
        <view class="selection-top">
          <text class="top-title">请选择地址区域</text>
          <image
            src="/static/image/bar-close.png"
            class="close-img"
            @tap="handleClickMask"
          />
        </view>
        <view class="selection-title">
          <text>省份</text>
          <text>城市</text>
          <text>区县</text>
        </view>
        <!-- 区域滚动选择 -->
        <picker-view
          class="picker-view"
          indicator-style="height:40px"
          mask-style="background-image: linear-gradient(to top, #ffffffcc,#fff, #fff)"
          @change="bindPickerChange"
          :value="value"
        >
          <!-- 省 -->
          <picker-view-column>
            <view
              class="item"
              :class="{ active: activeProvince === index }"
              v-for="(item, index) in provinces"
              :key="item.key"
              >{{ item.label }}</view
            >
          </picker-view-column>
          <!-- 市 -->
          <picker-view-column>
            <view
              class="item"
              :class="{ active: activeCity === index }"
              v-for="(item, index) in citys"
              :key="item.key"
              >{{ item.label }}</view
            >
          </picker-view-column>
          <!-- 县 -->
          <picker-view-column>
            <view
              class="item"
              :class="{ active: activeCounty === index }"
              v-for="(item, index) in countys"
              :key="item.key"
              >{{ item.label }}</view
            >
          </picker-view-column>
        </picker-view>
        <button type="default" class="confirm-btn" @click="confirmSelect">
          确认
        </button>
      </view>
    </view>
    <!-- 遮罩层 -->
    <view
      class="tui-actionsheet-mask"
      :class="[show ? 'tui-mask-show' : '']"
      @tap="handleClickMask"
    ></view>
  </view>
</template>

javaScript部分代码

<script>
import { reactive, toRefs, onBeforeMount, onMounted, nextTick } from "vue";
import { different } from "@/utils/common.js";
import {
  getEconomize,
  getMarket,
  getCounty,
} from "@/api/modules/common.api.js";   
// 以上省市县的接口,可根据开发实际情况前端写死或者后端请求数据
export default {
  name: "tuiActionsheet",
  props: {
    //点击遮罩 是否可关闭
    maskClosable: {
      type: Boolean,
      default: true,
    },
    //显示操作菜单
    show: {
      type: Boolean,
      default: false,
    },
    // 初始化显示的地区
    currentAddress: {
      type: Array,
    },
  },
  setup(props, ctx) {
    watch(
      () => props.show,
      (val) => {
        if (val) {
          data.provinces = [{ key: "0", label: "请选择" }];
          data.citys = [{ key: "1", label: "请选择" }];
          data.countys = [{ key: "2", label: "请选择" }];
          data.inCurrentAddress = props.currentAddress;
          inGetEconomize();
        }
      }
    );

    const data = reactive({
      inCurrentAddress: [],
      value: [0, 0, 0],
      provinces: [{ key: "0", label: "请选择" }],
      citys: [{ key: "1", label: "请选择" }],
      allCitys: [], //保存已请求的数据
      countys: [{ key: "2", label: "请选择" }],
      allCountys: [],
      activeProvince: 0,
      activeCity: 0,
      activeCounty: 0,
    });
    onBeforeMount(() => {});
    onMounted(() => {});
    // 获取省
    const inGetEconomize = () => {
      // 获取省数据
      getEconomize({ data: {} }).then((res) => {
        if (res.code) return;
        data.provinces.push(...res.data);
        dataHandle("provinces", 0);
      });
    };
    // 获取市
    const inGetCitys = (code) => {
      getMarket({ data: { marketCode: code } }).then((res) => {
        if (res.code) return;
        data.citys.push(...res.data);
        dataHandle("citys", 1);
      });
    };
    // 获取县
    const inGetCountys = (code) => {
      getCounty({ data: { countyCode: code } }).then((res) => {
        if (res.code) return;
        data.countys.push(...res.data);
        dataHandle("countys", 2);
      });
    };
    const dataHandle = (attribute, col) => {
      // data[attribute].unshift();
      const echo = data.inCurrentAddress[col];
      let index = data[attribute].findIndex((item) => item.label === echo);
      index = index < 0 ? 0 : index;
      setActiveStyle(col, index);
      const key = data[attribute][index].key;
      if (col === 0) {
        inGetCitys(key); //获取市
      }
      if (col === 1) {
        inGetCountys(key); //获取县
      }
    };
    // 设置选中值和样式
    const setActiveStyle = (column, index) => {
      nextTick(() => {
        // 设置初始化选中
        data.value[column] = index;
        setActiveValue(data.value);
      });
    };
    // 滚动选择
    const bindPickerChange = (e) => {
      const changeIndex = different(data.value, e.detail.value);
      data.value = e.detail.value;
      setActiveValue(data.value);
      changeSelectHandle(changeIndex);
    };
    const changeSelectHandle = (index) => {
      if (index === 0) {
        data.citys = data.citys.splice(0, 1);
        inGetCitys(data.provinces[data.value[0]].key); //获取市
      }
      if (index === 1) {
        data.countys = data.countys.splice(0, 1);
        if (data.citys.length) {
          inGetCountys(data.citys[data.value[1]].key); //获取县
        }
      }
    };
    // 设置选中项的index控制选中样式
    const setActiveValue = (arr) => {
      data.activeProvince = arr[0];
      data.activeCity = arr[1];
      data.activeCounty = arr[2];
    };
    // 确认选择
    const confirmSelect = () => {
      const { provinces, citys, countys, value } = data;
      const index = value.indexOf(0);
      if (index !== -1) {
        let msg;
        switch (index) {
          case 1:
            msg = "请选择城市";
            break;
          case 2:
            msg = "请选择区县";
            break;
          default:
            msg = "请选择省份";
        }

        uni.showToast({
          icon: "none",
          title: msg,
        });
      } else {
        const confirmArr = [
          provinces[value[0]],
          citys[value[1]],
          countys[value[2]],
        ];
        ctx.emit("confirm", confirmArr);
        handleClickCancel();
      }
    };
    // 点击遮罩层
    const handleClickMask = () => {
      if (!props.maskClosable) return;
      handleClickCancel();
    };
    // 点击取消
    const handleClickCancel = () => {
      ctx.emit("chooseCancel");
    };
    return {
      confirmSelect,
      handleClickMask,
      handleClickCancel,
      bindPickerChange,
      ...toRefs(data),
    };
  },
};
</script>

different方法判断数组中某个值的改变下标

export const different = (arr1, arr2) => {
    let index
    for (let i = 0; i < arr1.length; i++) {
        if (arr1[i] !== arr2[i]) {
            index = i
        }
    }
    return index
}

css样式代码


<style scoped lang="less">
.tui-actionsheet {
  width: 100%;
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 9999;
  visibility: hidden;
  transform: translate3d(0, 100%, 0);
  transform-origin: center;
  transition: all 0.3s ease-in-out;
  // background: #eaeaec;
  min-height: 100rpx;
}

.tui-actionsheet-show {
  transform: translate3d(0, 0, 0);
  visibility: visible;
}
.regional-selection {
  position: relative;
  text-align: center;
  height: 818rpx;
  background: #fff;
  border-radius: 32rpx 32rpx 2rpx 2rpx;
  overflow: hidden;
  .selection-top {
    height: 100rpx;
    line-height: 100rpx;
    position: absolute;
    top: 0;
    z-index: 9999;
    width: 100%;
    border-bottom: 1rpx solid #f4f6f9;
    .top-title {
      text-align: center;
      font-size: 30rpx;
      color: #262626;
      font-weight: 600;
    }
    .close-img {
      position: absolute;
      width: 50rpx;
      height: 50rpx;
      right: 24rpx;
      top: 25rpx;
    }
  }
  .selection-title {
    position: absolute;
    top: 100rpx;
    height: 100rpx;
    line-height: 100rpx;
    z-index: 9999;
    width: 100%;
    font-size: 30rpx;
    display: flex;
    color: #262626;
    justify-content: space-around;
  }
  .picker-view {
    width: 750rpx;
    height: 560rpx;
    margin-top: 20px;

    /deep/.uni-picker-view-content {
      padding: 0rpx 0 !important;
    }
    .item {
      height: 40px !important;
      line-height: 40px;
      text-align: center;
      font-size: 26rpx;
      color: #606266;
      font-weight: normal !important;
      &.active {
        color: #0080ff;
        font-size: 30rpx;
      }
    }
  }

  .confirm-btn {
    margin-top: 30rpx;
    height: 88rpx;
    width: 690rpx;
    font-size: 30rpx;
    border-radius: 16rpx;
    line-height: 88rpx;
    background: #0080ff;
    color: #fff;
    &::after {
      border: none;
    }
  }
}

.tui-actionsheet-mask {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(0, 0, 0, 0.6);
  z-index: 9996;
  transition: all 0.3s ease-in-out;
  opacity: 0;
  visibility: hidden;
}

.tui-mask-show {
  opacity: 1;
  visibility: visible;
}
</style>

效果预览

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

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

相关文章

你选的产品真的适合做独立站吗?用这5种方法测试一下吧!

跨境电商行业圈里流行一句话“七分靠选品&#xff0c;三分靠运营”&#xff0c;一个独立站新手卖家要想在跨境电商这个庞大的行业体系里分得一块蛋糕&#xff0c;不深入了解一些选品的技巧恐怕很难做出成绩来。 很多独立站赚不到钱的原因在于选品上的失败&#xff0c;如果你的…

蓝绿灰度发布的介绍

背景介绍 蓝绿灰度发布 介绍 蓝绿部署中&#xff0c;一共有两套系统&#xff1a;一套是正在提供服务系统(也就是上面说的旧版)&#xff0c;标记为绿色&#xff1b;另一套是准备发布的系统&#xff0c;标记为蓝色。两套系统都是功能完善的&#xff0c;并且正在运行的系统&…

个微CRM管理系统,都有哪些功能?

微信CRM管理系统是一种优化整个公司的工作流程以改善客户管理的工具。 不仅可以提升微信CRM管理系统的创建&#xff0c;还可以提升现有客户的质量。 那么很多人就想问&#xff0c;微信CRM管理系统都有哪些功能呢&#xff1f; 1、多个微信号聚合聊天&#xff0c;解决微信来回…

通达信接口怎么调用?(通达信量化接口)准确吗?

通达信(DXFeed/TDX)接口是一个常用的股票行情数据接口&#xff0c;在中国股市数据分析和量化交易中应用广泛。下面我将介绍一种通达信接口的调用方式&#xff0c;但请注意&#xff0c;该方式可能存在变化和不准确之处&#xff0c;具体的调用方式还需参考官方文档或其他可靠来源…

Redis数据结构——字典

字典是一种用来保存键值对的数据结构。 在字典中&#xff0c;一个key与一个value相对应&#xff0c;字典中的key是唯一的。 在Redis中字典使用哈希表作为底层实现&#xff0c;用数组来表示一个哈希表&#xff0c;每个元素都是一对key-value 同样&#xff0c;在Redis中字典由三…

【笔试题心得】关于KMP在笔试中的题型

好几家都考到KMP了 问的比较多的是 next数组 &#xff0c; 其实KMP的相关机制我在代码随想录算法训练营第九天|KMP算法_菜鸟的Zoom之旅的博客-CSDN博客中写道过&#xff0c;现在在复习一下&#xff0c;由于next数组的定义其实会有所歧义&#xff08;有些程序中会直接将前缀表作…

C++专题--标准模板库STL

c专题-标准模板库STL 1 标准模板库概述 2 序列式容器 2.1 vector 容器 2.2 deque 容器 2.3 list 容器 3 关联式容器 4 无序关联容器 5 容器适配器 5.1 STL容器适配器的种类 5.2 stack容器适配器 5.3 queue容器适配器 5.3 priority_queue容器适配器…

Mac RN环境搭建

RN ios android原生环境搭建有时候是真恶心&#xff0c;电脑环境不一样配置也有差异。 我已经安装官网的文档配置了ios环境 执行 npx react-nativelatest init AwesomeProject 报错 然后自己百度查呀执行 gem update --system 说是没有权限&#xff0c;执行失败。因为Mac…

SQL Server2019安装后使用SQL Server身份验证登录失败

错误情况 今天在电脑安装SQL Server2019和SMMS&#xff0c;安装过程一切顺利&#xff0c;但是在使用SMMS连接数据库时出现了异常。使用"Window 身份验证"登录时正常&#xff0c;但是如果改为使用"SQL Server 身份验证"登录时却连接失败&#xff01; 解决方…

两张图搞定前端面试特别常重要的知识点:defer和async的区别

渲染引擎解析<script>的过程 <script>标签上有defer或async属性&#xff0c;脚本就会异步加载。渲染引擎遇到这一行命令&#xff0c;就会开始下载外部脚本&#xff0c;但不会等它下载和执行&#xff0c;而是直接执行后面的命令&#xff1b;默认情况是渲染引擎遇到…

微信开发之一键扫码入群的技术实现

好友将群二维码发送给机器人&#xff0c;机器人调用本接口将自动识别入群 请求URL&#xff1a; http://域名地址/scanJoinRoom 请求方式&#xff1a; POST 请求头Headers&#xff1a; Content-Type&#xff1a;application/jsonAuthorization&#xff1a;login接口返回 …

MS2692宽带低噪声放大器

MS2692 是一款宽带低噪声放大器&#xff0c;工作频率 0.45GHz  5.0GHz 。 具有高线性度、低噪声、带内增益平坦等特点。在 0.85GHz  4.0GHz 频带内&#xff0c;增益波动小于 3dB 。在 0.85GHz  5.0GHz 频带内&#xff0c;噪声系数 小于 1.2dB 。内部集成偏…

文件批量改名高手:轻松删除文件名,仅保留编号!

您是否经常需要对大量文件进行命名调整&#xff1f;是否为繁琐的手动操作而感到厌烦&#xff1f;现在&#xff0c;我们的智能批量文件改名工具为您提供了一种简单而高效的解决方案&#xff01;只需几步操作&#xff0c;您就能轻松删除原有的文件名&#xff0c;仅保留编号&#…

Oracle-如何判断字符串包含中文字符串(汉字),删除中文内容及保留中文内容

今天遇见一个问题需要将字段中包含中文字符串的筛选出来 --建表 CREATE TABLE HADOOP1.AAA ( ID VARCHAR2(255) ); --添加字段INSERT INTO HADOOP1.AAA(ID)VALUES(理解);....--查询表内容SELECT * FROM HADOOP1.AAA;在网上查找了一下有以下三种方式&#xff1a; 第一种&#…

新的 Python URL 解析漏洞可能导致命令执行攻击

Python URL 解析函数中的一个高严重性安全漏洞已被披露&#xff0c;该漏洞可绕过 blocklist 实现的域或协议过滤方法&#xff0c;导致任意文件读取和命令执行。 CERT 协调中心&#xff08;CERT/CC&#xff09;在周五的一份公告中说&#xff1a;当整个 URL 都以空白字符开头时&…

智慧建筑工地平台,通过信息化技术、物联网、人工智能技术,实现对施工全过程的实时监控、数据分析、智能管理和优化调控

智慧工地是指通过信息化技术、物联网、人工智能技术等手段&#xff0c;对建筑工地进行数字化、智能化、网络化升级&#xff0c;实现对施工全过程的实时监控、数据分析、智能管理和优化调控。智慧工地的建设可以提高工地的安全性、效率性和质量&#xff0c;降低施工成本&#xf…

BBS-个人博客项目完整搭建、BBS多人博客项目基本功能和需求、项目程序设计、BBS数据库表结构设计、创建BBS表模型

一、BBS-个人博客项目完整搭建 项目开发流程 一、项目分类 现在互联网公司需要开发的主流web项目一般分为两类&#xff1a;面向互联网用户&#xff0c;和公司内部管理。面向互联网用户: C(consumer)端项目 公司内部管理&#xff1a;B(business)端项目还有一类web应用&#xff…

jeecg-boot批量导入问题注意事项

现象&#xff1a; 由于批量导入数据速度很快&#xff0c; 因为数据库中的create time字段的时间可能一样&#xff0c;并且jeecg框架自带的是根据生成时间排序&#xff0c; 因此在前端翻页查询的时候&#xff0c;数据每次排序可能会不一样&#xff0c; 会出现第一页已经出现过一…

Qt读写Excel--QXlsx编译为静态库2

1、概述&#x1f954; 在使用QXlsx时由于源码文件比较多&#xff0c;如果直接加载进项目里面&#xff0c;会增加每次编译的时间&#xff1b; 直接将源码加载进项目工程中&#xff0c;会导致项目文件非常多&#xff0c;结构变得更加臃肿&#xff1b; 所以在本文中将会将QXlsx编译…

三维可视化平台有哪些?Sovit3D可视化平台怎么样?

随着社会经济的发展和数字技术的进步&#xff0c;互联网行业发展迅速。为了适应新时代社会发展的需要&#xff0c;大数据在这个社会经济发展过程中随着技术的进步而显得尤为重要。同时&#xff0c;大数据技术的快速发展进程也推动了可视化技术的飞速发展&#xff0c;国内外各类…