个人项目地址: SubTopH前端开发个人站
(自己开发的前端功能和UI组件,一些有趣的小功能,感兴趣的伙伴可以访问,欢迎提出更好的想法,私信沟通,网站属于静态页面)
SubTopH前端开发个人站https://subtop.gitee.io/subtoph.github.io/#/home
以上 👆 是个人前端项目,欢迎提出您的建议😊
实现效果
功能介绍:
- 支持默认值直接显示滚动定位
- 选择上一次后,下一级重置请选择
- 选中样式可自定义
- 点击确认可校验省市县时候全部选择
直接上代码模板部分(利用uniapp中的picker-view进一步封装)
<template><view><viewclass="tui-actionsheet-class tui-actionsheet":class="[show ? 'tui-actionsheet-show' : '']"><view class="regional-selection"><view class="selection-top"><text class="top-title">请选择地址区域</text><imagesrc="/static/image/bar-close.png"class="close-img"@tap="handleClickMask"/></view><view class="selection-title"><text>省份</text><text>城市</text><text>区县</text></view><!-- 区域滚动选择 --><picker-viewclass="picker-view"indicator-style="height:40px"mask-style="background-image: linear-gradient(to top, #ffffffcc,#fff, #fff)"@change="bindPickerChange":value="value"><!-- 省 --><picker-view-column><viewclass="item":class="{ active: activeProvince === index }"v-for="(item, index) in provinces":key="item.key">{{ item.label }}</view></picker-view-column><!-- 市 --><picker-view-column><viewclass="item":class="{ active: activeCity === index }"v-for="(item, index) in citys":key="item.key">{{ item.label }}</view></picker-view-column><!-- 县 --><picker-view-column><viewclass="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><!-- 遮罩层 --><viewclass="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 indexfor (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>
效果预览