qq空间刷赞网站推广南京个人网站建设模板
web/
2025/10/3 23:55:22/
文章来源:
qq空间刷赞网站推广,南京个人网站建设模板,虫点子创意设计公司,粤icp备案号查询网官网为啥不直接用Cascader 级联选择组件呢#xff1f;主要是因为作为老项目#xff0c;已经引入了antd-mobile2.3.4#xff0c;同时引入v5版本会有兼容性问题。
原始数据格式#xff1a;
首先需要将后端返回的数据转为前端定义的格式#xff0c;方便使用#xff1a;
[{主要是因为作为老项目已经引入了antd-mobile2.3.4同时引入v5版本会有兼容性问题。
原始数据格式
首先需要将后端返回的数据转为前端定义的格式方便使用
[{label: 安徽省,value: 340000,children: [{label: 安庆市,value: 340800,children: [{label: 大观区,value: 340803,children: []},...其他区]},...其他市]},...其他省份
]树结构转数组结构
研究了下antd-mobile的cascader-view源码我发现精髓在于将树结构转换成了方便开发的数组 //选择的value 一维数组const [value, setValue] useState([]);const levels useMemo(() {const ret [];//当前列表let currentOptions options;//是否到底let reachedEnd false;for (const v of value) {const target currentOptions.find(option option[value] v);ret.push({selected: target,options: currentOptions,});if (!target || !target[children] || isEmpty(target[children])) {reachedEnd true;break;}currentOptions target[children];}if (!reachedEnd) {ret.push({selected: undefined,options: currentOptions,});}return ret;}, [value]);当未选择时levels结构
[{//未选中selected: undefined,options: [{label: 安徽省,value: 340000,children: [{label: 安庆市,value: 340800,children: [{label: 大观区,value: 340803,children: []},...其他区]},...其他市]},...其他省份]}
]选中省份时levels结构
[{//选中省份selected: {label: 安徽省,value: 340000,children: [{label: 安庆市,value: 340800,children: [{label: 大观区,value: 340803,children: []},...其他区]},...其他市]}, options: [{label: 安徽省,value: 340000,children: [{label: 安庆市,value: 340800,children: [{label: 大观区,value: 340803,children: []},...其他区]},...其他市]},...其他省份]},{//未选中selected: undefined,options: [{label: 安庆市,value: 340800,children: [{label: 大观区,value: 340803,children: []},...其他区]},...其他市]}
]数据结构清楚以后编码就相对简单了
import PopShow from /components/PopShow;
import React, { useMemo, useState } from react;
//v2版本的
import { Tabs } from antd-mobile;
import styles from ./index.less;
import { isEmpty } from lodash;
import { CheckOutline } from antd-mobile-icons;
import classNames from classnames;const AddressModal ({options}) {const [value, setValue] useState([]);const [page, setPage] useState(0);//精髓在于这段代码将树形结构转为数组const levels useMemo(() {const ret [];//当前列表let currentOptions options;//是否到底let reachedEnd false;for (const v of value) {const target currentOptions.find(option option[value] v);ret.push({selected: target,options: currentOptions,});if (!target || !target[children] || isEmpty(target[children])) {reachedEnd true;break;}currentOptions target[children];}if (!reachedEnd) {ret.push({selected: undefined,options: currentOptions,});}return ret;}, [value]);const tabs useMemo(() {const ret levels?.map(level {if (level?.selected) {return {title: level?.selected[label],};}return {title: 请选择,};}) || [{title: 请选择,}];//滑动到下一tabsetPage(ret?.length - 1);return ret;}, [levels]);const onItemSelect (selectValue, depth) {const next value.slice(0, depth);if (selectValue ! undefined) {next[depth] selectValue;}setValue(next);};return PopShow visible{true}div className{styles.popShow}div className{styles.topButtons}span取消/spanspan确定/span/divTabs tabs{tabs} swipeable{false} page{page}onChange{(_, index) setPage(index)}tabBarActiveTextColor{#BB6532}tabBarInactiveTextColor{#000000}tabBarUnderlineStyle{{ display: none }}tabBarTextStyle{{ fontSize: 14px }}{levels?.map((level, index) {const options level?.options;return (div className{styles.checklist}{options?.map(option {const active value[index] option[value];return div onClick{() onItemSelect(option[value], index)}className{classNames({[styles.active]: active})}span{option[label]}/span{active CheckOutline /}/div;})}/div);})}/Tabs/div/PopShow;
};export default AddressModal;import (reference) ../../styles/index.less;.popShow {height: 60vh;display: flex;flex-direction: column;overflow: hidden;.topButtons {display: flex;justify-content: space-between;padding: 8*rem 16*rem 4*rem;color: #343434;}.checklist {flex: 1;overflow-y: scroll;::-webkit-scrollbar {display: none;} div {text-align: left;padding: 8*rem 16*rem;display: flex;justify-content: space-between;align-items: center;}.active{color: #BB6532;}}:global {.am-tabs-default-bar-tab {width: auto !important;padding-left: 16*rem;padding-right: 16*rem;max-width: 33.3%;.textEllipsis;}.am-tabs-default-bar-content {position: relative;:after {content: ;position: absolute;background-color: #ddd;display: block;z-index: 1;top: auto;right: auto;bottom: 0;left: 0;width: 100%;height: 1px;}}}
}附上效果图
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/86484.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!