項目急求,伸手黨小白求一個三級聯(lián)動地區(qū)選擇組件。
項目里正好有一個
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';
import Selector from './selector';
import Model from '../model/model';
import * as API from '../constants/api';
class Location extends Component {
static propTypes = {
province: PropTypes.shape({
id: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
name: PropTypes.string
}),
city: PropTypes.shape({
id: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
name: PropTypes.string
}),
district: PropTypes.shape({
id: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
name: PropTypes.string
}),
validating: PropTypes.bool, // 是否驗證location值得有效性
static: PropTypes.bool,
hasCode: PropTypes.bool,
required: PropTypes.bool,
onFetchProvinces: PropTypes.func,
onFetchCities: PropTypes.func,
onFetchDistricts: PropTypes.func,
onChangeLocation: PropTypes.func,
onError: PropTypes.func,
onSetState: PropTypes.func
}
static defaultProps = {
province: {},
city: {},
district: {},
static: false,
hasCode: false,
onChangeLocation: () => {},
onError: obj => alert(obj.message),
onSetState: () => {}
}
constructor(props) {
super(props);
this.state = {
provinces: [],
cities: [],
districts: []
};
this.initComponent(props);
this.cacheData = {
provinces: {},
cities: {},
districts: {}
}
}
componentWillReceiveProps(nextProps) {
const { province: nextProvince, city: nextCity, district: nextDistrict } = nextProps;
const { province, city, district } = this.props;
if (nextProvince && (!province || nextProvince.id !== province.id)) {
const provincesCacheData = this.cacheData.provinces;
const citiesCacheData = this.cacheData.cities;
const nextProvinceId = nextProvince.id;
if (citiesCacheData[nextProvinceId]) {
const nextState = { cities: citiesCacheData[nextProvinceId].items };
this.setState(nextState, () => this.props.onSetState(nextState));
} else {
this.handleFetchCities(nextProvinceId);
}
}
if (nextCity && (!city || nextCity.id !== city.id)) {
const citiesCacheData = this.cacheData.cities;
const districtsCacheData = this.cacheData.districts;
const nextProvinceId = nextProvince.id;
const nextCityId = nextCity.id;
if (districtsCacheData[`${nextProvinceId}_${nextCityId}`]) {
const nextState = { districts: districtsCacheData[`${nextProvinceId}_${nextCityId}`].items };
this.setState(nextState, () => this.props.onSetState(nextState));
} else {
this.handleFetchDistricts(nextProvinceId, nextCityId);
}
}
}
fetchProvinces = () => {
return new Promise((resolve, reject) => {
const model = Model.getInstance();
model.url = API.API_FETCH_PROVINCES;
// model.setParam({ countryId: CONSTANTS.CATEGORY_TYPE_COOKING });
model.execute((data) => {
resolve(data.data || []);
}, (err) => {
if ('status' in err && err.status === 0) {
this.props.onError({
status: 'error',
message: '獲取省份失敗'
});
}
reject();
}, this);
});
}
fetchCities = (provinceId, callback) => {
return new Promise((resolve, reject) => {
const model = Model.getInstance();
model.url = API.API_FETCH_CITIES;
model.setParam({ provinceId, hasCode: this.props.hasCode ? 1 : 0 });
model.execute((data) => {
const cities = [];
for (const city of (data.data.dataList || [])) {
cities.push({ id: city.cityId, name: city.cityName, shouzimu: city.shouzimu });
}
resolve(cities);
}, (err) => {
if ('status' in err && err.status === 0) {
this.props.onError({
status: 'error',
message: '獲取城市失敗'
});
}
reject();
}, this);
});
}
fetchDistricts = (provinceId, cityId, callback) => {
return new Promise((resolve, reject) => {
const model = Model.getInstance();
model.url = API.API_FETCH_DISTRICTS;
model.setParam({ provinceId, cityId, hasCode: this.props.hasCode ? 1 : 0 });
model.execute((data) => {
resolve(data.data.dataList || []);
}, (err) => {
if ('status' in err && err.status === 0) {
this.props.onError({
status: 'error',
message: '獲取市縣失敗'
});
}
reject();
}, this);
});
}
handleSelectProvince = (provinceId) => {
if (!this.props.province || provinceId !== this.props.province.id) {
const provincesCacheData = this.cacheData.provinces;
const citiesCacheData = this.cacheData.cities;
if (citiesCacheData[provinceId]) {
const nextState = { cities: citiesCacheData[provinceId].items };
this.setState(nextState, () => this.props.onSetState(nextState));
}
const province = { id: provinceId, name: (provincesCacheData[provinceId] || {}).name };
this.props.onChangeLocation({ province, city: null, district: null });
this.setState({ districts: [] }, () => this.props.onSetState({ districts: [] }));
}
}
handleSelectCity = (cityId) => {
if (!this.props.city || cityId !== this.props.city.id) {
const citiesCacheData = this.cacheData.cities;
const districtsCacheData = this.cacheData.districts;
const { province: { id: provinceId } } = this.props;
if (districtsCacheData[`${provinceId}_${cityId}`]) {
const nextState = { districts: districtsCacheData[`${provinceId}_${cityId}`].items };
this.setState(nextState, () => this.props.onSetState(nextState));
}
const city = { id: cityId, name: (citiesCacheData[provinceId][cityId] || {}).name };
this.props.onChangeLocation({ city, district: null });
}
}
handleSelectDistrict = (districtId) => {
const { province: { id: provinceId }, city: { id: cityId } } = this.props;
const districtsCacheData = this.cacheData.districts;
const district = { id: districtId, name: (districtsCacheData[`${provinceId}_${cityId}`][districtId] || {}).name };
this.props.onChangeLocation({ district });
}
handleFetchProvinces = () => {
const fetchProvinces = this.props.onFetchProvinces || this.fetchProvinces;
fetchProvinces().then(provinces => {
this.updatedProvincesToCache(provinces);
const nextState = { provinces: this.cacheData.provinces.items };
this.setState(nextState, () => this.props.onSetState(nextState));
});
}
handleFetchCities = (provinceId) => {
const fetchCities = this.props.onFetchCities || this.fetchCities;
fetchCities(provinceId).then(cities => {
this.updatedCitiesToCache(provinceId, cities);
const nextState = { cities: this.cacheData.cities[provinceId].items };
this.setState(nextState, () => this.props.onSetState(nextState));
});
}
handleFetchDistricts = (provinceId, cityId) => {
const fetchDistricts = this.props.onFetchDistricts || this.fetchDistricts;
fetchDistricts(provinceId, cityId).then(districts => {
this.updatedDistrictsToCache(provinceId, cityId, districts);
const nextState = { districts: this.cacheData.districts[`${provinceId}_${cityId}`].items };
this.setState(nextState, () => this.props.onSetState(nextState));
});
}
initComponent = (props) => {
const { province, city, district } = props;
this.handleFetchProvinces();
if (province.id) {
this.handleFetchCities(province.id);
if (city.id) {
this.handleFetchDistricts(province.id, city.id);
}
}
}
validateProvince = () => {
const { province } = this.props;
return province && province.id;
}
validateCity = () => {
const { city } = this.props;
return (city && city.id) || (this.validateProvince() && (!this.state.cities || !this.state.cities.length) && (!city || !city.id));
}
validateDistrict = () => {
const { district } = this.props;
return (district && district.id) || (this.validateCity() && (!this.state.districts || !this.state.districts.length) && (!district || !district.id));
}
updatedProvincesToCache = (provinces) => {
this.cacheData.provinces = {};
const provincesCacheData = this.cacheData.provinces;
for (const province of (provinces || [])) {
provincesCacheData[province.id] = {
name: province.name,
cities: {}
};
}
provincesCacheData.items = provinces;
}
updatedCitiesToCache = (provinceId, cities) => {
const citiesCacheData = {};
const items = [];
for (const city of (cities || [])) {
citiesCacheData[city.id] = {
name: city.name,
shouzimu: city.shouzimu,
districts: {}
};
items.push({ ...city });
}
citiesCacheData.items = items;
this.cacheData.cities[provinceId] = citiesCacheData;
}
updatedDistrictsToCache = (provinceId, cityId, districts) => {
const districtsCacheData = {};
const items = [];
for (const district of (districts || [])) {
districtsCacheData[district.id] = {
name: district.name
};
items.push({ ...district });
}
districtsCacheData.items = items;
this.cacheData.districts[`${provinceId}_${cityId}`] = districtsCacheData
}
render() {
const province = this.props.province || {};
const city = this.props.city || {};
const district = this.props.district || {};
const { provinces, cities, districts } = this.state;
const { validating } = this.props;
const isProvinceValid = this.validateProvince();
const isCityValid = this.validateCity();
const isDistrictValid = this.validateDistrict();
return (
<div className="mw-location">
<div className="mw-location-column mw-location-provinces">
<Selector
className={classNames('mw-form-control', { error: !!validating && !isProvinceValid })}
value={province.id}
options={provinces}
valueField="id"
labelField="name"
placeholder="請選擇省份"
onChange={this.handleSelectProvince}
/>
</div>
<div className="mw-location-column mw-location-cities">
<Selector
className={classNames('mw-form-control', { error: !!validating && !isCityValid })}
value={city.id}
options={cities}
valueField="id"
labelField="name"
placeholder="請選擇城市"
onChange={this.handleSelectCity}
/>
</div>
<div className="mw-location-column mw-location-districts">
<Selector
className={classNames('mw-form-control', { error: !!validating && !isDistrictValid })}
value={district.id}
options={districts}
valueField="id"
labelField="name"
placeholder="請選擇區(qū)縣"
onChange={this.handleSelectDistrict}
/>
</div>
</div>
);
}
}
export default Location;
<Picker
mode='date'
title='選擇血站'
cols={2} // 顯示2列 二級聯(lián)動
data={bloodcenter} // 血液中心全國地址 (放進你需要的城市三級聯(lián)動,按照規(guī)定的格式)
{...getFieldProps('donationLocation', {
rules: [{ required: true, message: '選擇血站' }],
initialValue: this.state.donationLocation, // 默認選擇深圳
onChange (value) {
slef.setState({
donationLocation: value
})
}
})}
>
<Item arrow='horizontal'>上次獻血地點</Item>
</Picker>
用的是ant-design-mobile 中的插件 你可以參考一下 全國三級聯(lián)動我這邊寫了一個js直接轉(zhuǎn)換成了ant需要的格式
北大青鳥APTECH成立于1999年。依托北京大學優(yōu)質(zhì)雄厚的教育資源和背景,秉承“教育改變生活”的發(fā)展理念,致力于培養(yǎng)中國IT技能型緊缺人才,是大數(shù)據(jù)專業(yè)的國家
北大青鳥中博軟件學院創(chuàng)立于2003年,作為華東區(qū)著名互聯(lián)網(wǎng)學院和江蘇省首批服務外包人才培訓基地,中博成功培育了近30000名軟件工程師走向高薪崗位,合作企業(yè)超4
中公教育集團創(chuàng)建于1999年,經(jīng)過二十年潛心發(fā)展,已由一家北大畢業(yè)生自主創(chuàng)業(yè)的信息技術(shù)與教育服務機構(gòu),發(fā)展為教育服務業(yè)的綜合性企業(yè)集團,成為集合面授教學培訓、網(wǎng)
達內(nèi)教育集團成立于2002年,是一家由留學海歸創(chuàng)辦的高端職業(yè)教育培訓機構(gòu),是中國一站式人才培養(yǎng)平臺、一站式人才輸送平臺。2014年4月3日在美國成功上市,融資1
曾工作于聯(lián)想擔任系統(tǒng)開發(fā)工程師,曾在博彥科技股份有限公司擔任項目經(jīng)理從事移動互聯(lián)網(wǎng)管理及研發(fā)工作,曾創(chuàng)辦藍懿科技有限責任公司從事總經(jīng)理職務負責iOS教學及管理工作。
浪潮集團項目經(jīng)理。精通Java與.NET 技術(shù), 熟練的跨平臺面向?qū)ο箝_發(fā)經(jīng)驗,技術(shù)功底深厚。 授課風格 授課風格清新自然、條理清晰、主次分明、重點難點突出、引人入勝。
精通HTML5和CSS3;Javascript及主流js庫,具有快速界面開發(fā)的能力,對瀏覽器兼容性、前端性能優(yōu)化等有深入理解。精通網(wǎng)頁制作和網(wǎng)頁游戲開發(fā)。
具有10 年的Java 企業(yè)應用開發(fā)經(jīng)驗。曾經(jīng)歷任德國Software AG 技術(shù)顧問,美國Dachieve 系統(tǒng)架構(gòu)師,美國AngelEngineers Inc. 系統(tǒng)架構(gòu)師。