taro3.x: 简单实现城市选择

tsx:

import React, { useEffect, useState } from 'react'
import Taro from '@tarojs/taro'
import { View, ScrollView } from '@tarojs/components'

import api from '@services/api'
import app from '@services/request'
import storage from '@utils/storage'
import NavBar from '@components/navbar'
import useNavData from '@hooks/useNavData'
import './index.scss'

const INIT_VIEW = 'hot'
const INIT_CITY_DATA = { city: {}, hotCity: [] }

const City = () => {
    const { appHeaderHeight, contentHeight } = useNavData()
    const [viewInto, setViewInto] = useState<string>(INIT_VIEW)
    const [cityData, setCityData] = useState<any>(INIT_CITY_DATA)

    useEffect(() => {
        app.request({
            url: app.testApiUrl(api.getCityList)
        }).then((result: any) => {
            setCityData(result || [])
        })
    }, [])

    const handleCityClick = (city: any) => {
        storage.setItem('city', city)
        Taro.navigateBack({
            delta: 1
        })
    }

    const renderCityList = (cityList: any) => {
        return (
            <View className="city-item-list">
                {
                    cityList.length > 0 &&
                    cityList.map((item: any, index: number) => (
                        <View
                            key={index}
                            className="city-name"
                            onClick={() => handleCityClick(item)}
                        >{item.short_name}
                        </View>
                    ))
                }
            </View>
        )
    }

    return (
        <View className="city">
            <NavBar title="切换城市" back={true}></NavBar>
            {/* <View className="fixd city-search">
                <View className="search-content">
                    <Text className="iconfont iconsearch"></Text>
                    <Input placeholder="请输入城市名" />
                </View>
            </View> */}
            <ScrollView
                scrollY
                className="city-content"
                style={{ height: contentHeight }}
                scrollIntoView={viewInto}
            >
                <View className="city-list">
                    <View className="city-item">
                        <View className="city-item-order" id={INIT_VIEW}>热门城市</View>
                        {renderCityList(cityData.hotCity)}
                    </View>
                    {
                        Object.keys(cityData.city).map((key: string, index: number) => (
                            <View className="city-item" key={index}>
                                <View className="city-item-order" id={key}>{key}</View>
                                {renderCityList(cityData.city[key])}
                            </View>
                        ))
                    }
                </View>
            </ScrollView>
            <View className="city-order" style={{ top: appHeaderHeight, height: contentHeight }}>
                <View className="city-order-list">
                    <View
                        className="order-item"
                        onClick={() => setViewInto(INIT_VIEW)}
                    >热门
                    </View>
                    {
                        Object.keys(cityData.city).map((key: string, index: number) => (
                            <View
                                key={index}
                                className="order-item"
                                onClick={() => setViewInto(key)}
                            >{key}
                            </View>
                        ))
                    }
                </View>
            </View>
        </View>
    )
}

export default City

知识点:navigateBack实现更新数据使用useDidShow()

data:

{
                    "city": {
                        "h": [
                            {
                                "id": "1000005",
                                "agent_id": "101",
                                "area_id": "131100",
                                "area_name": "衡水市",
                                "short_name": "衡水",
                                "alias": "hengshui",
                                "alias_index": "h",
                                "is_hot": "2"
                            }
                        ],
                        "s": [
                            {
                                "id": "1000026",
                                "agent_id": "97",
                                "area_id": "420300",
                                "area_name": "十堰市",
                                "short_name": "十堰",
                                "alias": "shiyan",
                                "alias_index": "s",
                                "is_hot": "2"
                            },
                            {
                                "id": "1000028",
                                "agent_id": "97",
                                "area_id": "421300",
                                "area_name": "随州市",
                                "short_name": "随州",
                                "alias": "suizhou",
                                "alias_index": "s",
                                "is_hot": "2"
                            },
                            {
                                "id": "1000029",
                                "agent_id": "97",
                                "area_id": "421400",
                                "area_name": "上海",
                                "short_name": "上海",
                                "alias": "shanghai",
                                "alias_index": "s",
                                "is_hot": "2"
                            },
                            {
                                "id": "1000030",
                                "agent_id": "97",
                                "area_id": "421500",
                                "area_name": "深圳市",
                                "short_name": "深圳",
                                "alias": "shenzhen",
                                "alias_index": "s",
                                "is_hot": "2"
                            },
                            {
                                "id": "1000031",
                                "agent_id": "97",
                                "area_id": "421600",
                                "area_name": "苏州",
                                "short_name": "苏州",
                                "alias": "suzou",
                                "alias_index": "s",
                                "is_hot": "2"
                            },
                            {
                                "id": "1000032",
                                "agent_id": "97",
                                "area_id": "421700",
                                "area_name": "沈阳",
                                "short_name": "沈阳",
                                "alias": "shenyang",
                                "alias_index": "s",
                                "is_hot": "2"
                            },
                            {
                                "id": "1000033",
                                "agent_id": "97",
                                "area_id": "421800",
                                "area_name": "汕头",
                                "short_name": "汕头",
                                "alias": "shantou",
                                "alias_index": "s",
                                "is_hot": "2"
                            },
                            {
                                "id": "1000034",
                                "agent_id": "97",
                                "area_id": "421900",
                                "area_name": "韶关",
                                "short_name": "韶关",
                                "alias": "shouguan",
                                "alias_index": "s",
                                "is_hot": "2"
                            },
                            {
                                "id": "1000035",
                                "agent_id": "97",
                                "area_id": "422000",
                                "area_name": "石家庄",
                                "short_name": "石家庄",
                                "alias": "shijiazhuang",
                                "alias_index": "s",
                                "is_hot": "2"
                            }
                        ],
                        "w": [
                            {
                                "id": "1000025",
                                "agent_id": "97",
                                "area_id": "420100",
                                "area_name": "武汉市",
                                "short_name": "武汉",
                                "alias": "wuhan",
                                "alias_index": "w",
                                "is_hot": "1"
                            }
                        ],
                        "x": [
                            {
                                "id": "1000006",
                                "agent_id": "101",
                                "area_id": "420600",
                                "area_name": "襄阳市",
                                "short_name": "襄阳",
                                "alias": "xiangyang",
                                "alias_index": "x",
                                "is_hot": "1"
                            }
                        ],
                        "y": [
                            {
                                "id": "1000027",
                                "agent_id": "97",
                                "area_id": "420500",
                                "area_name": "宜昌市",
                                "short_name": "宜昌",
                                "alias": "yichang",
                                "alias_index": "y",
                                "is_hot": "2"
                            }
                        ]
                    },
                    "hotCity": [
                        {
                            "id": "1000025",
                            "agent_id": "97",
                            "area_id": "420100",
                            "area_name": "武汉市",
                            "short_name": "武汉",
                            "alias": "wuhan",
                            "alias_index": "w",
                            "is_hot": "1"
                        },
                        {
                            "id": "1000006",
                            "agent_id": "101",
                            "area_id": "420600",
                            "area_name": "襄阳市",
                            "short_name": "襄阳",
                            "alias": "xiangyang",
                            "alias_index": "x",
                            "is_hot": "1"
                        }
                    ]
                }

scss:

.city {
    width: 100%;
    height: 100vh;
    background-color: $bg-color;
    &-search {
        padding: 20px 30px;
        background-color: $bg2-color;
        .search-content {
            display: flex;
            height: 70px;
            line-height: 70px;
            background-color: $white;
            border-radius: $border-radius-base;
            .iconfont {
                padding: 0 20px;
            }
            Input {
                flex: 1;
                height: 70px;
                line-height: 70px;
                font-size: $font-basic;
            }
        }
    }

    &-content {
        .city-empty {
            padding: 30px 0;
            font-size: $font-basic;
            text-align: center;
            color: $desc-color;
        }

        .city-list {
            .city-item {
                &-order {
                    height: 60px;
                    line-height: 60px;
                    padding: 0 30px;
                }
                &-list {
                    background-color: $white;

                    .city-name {
                        padding: 20px 30px;
                        border-bottom: $border;
                    }
                }
            }
        }
    }

    &-order{
        position: fixed;
        right: 10px;
        width: 10%;
        text-align: center;
        font-size: $font-26;
        color: $primary-color;

        &-list {
            position: absolute;
            top: 50%;
            left: 50%;
            width: 100%;
            transform: translate(-50%, -50%);
            padding: 24px 0; 
            .order-item {
                padding: 6px 0; 
            }
        }
    }
}
原文地址:https://www.cnblogs.com/Nyan-Workflow-FC/p/13725568.html