中國行政區劃信息JS庫china-location

常常會在一些項目中用到地址選擇的東西,特別是在一些在線商城要填寫收貨地址的時候,省市區3個聯動的下拉列表是最經常使用的。而後我也忽然有一天在一個小項目中要有收貨地址時,忽然發現好像沒有一個現成的庫(要能直接npm install xxx)去使用😰,而後在github去搜了一圈,確實發現有json格式的原始數據,可是結構是同一級的,很難區分是省仍是市或者區,雖然做者提供了jquery的插件,可是畢竟是在手機端使用,最好仍是能直接經過js去操做(這樣在nodejs服務端也能使用)。因此決定把原始數據進行從新格式化,轉成省市區嵌套的格式,這樣的話就很容易經過省的ID去拿到市的列表,而後經過市的ID又能拿到區的列表,這正是咱們的聯動下拉列表想要的結構。javascript

結構設定

最終要想的結構以下:html

{
    "320000": {
        "code": "320000",
        "name": "江蘇省",
        "cities": {
            "320100": {
                "code": "320100",
                "name": "南京市",
                "districts": {
                    "320102": "玄武區",
                    "320104": "秦淮區",
                    //...
                }
            }
            //...
        }
    }
    //...
}
複製代碼

咱們經過code的前2位來肯定省,中間2位來肯定市,最後2位來肯定區,因此若是是前兩位同樣的就說明是屬於同一個省的,中間2個同樣的就說明是同一個市的,以此類推,須要注意的是上海北京這樣的直轄市,省跟市都是上海,市的code爲00,並且只有一個市,下面的區的中間2位code均爲01,這裏在轉數據的時候須要注意。java

使用 china-location 庫

基於上面的邏輯,寫了個簡單的轉換的js,並提供簡單的API來直接給外面調用🍺。 首先安裝庫china-location:node

npm install china-location --save
複製代碼

或者react

yarn add china-location
複製代碼

而後在JS裏面jquery

//跟庫一塊兒綁定轉換好的數據
import list from 'china-location/dist/location.json'
//in node.js
//const list = require('china-location/dist/location.json');

//ES6 import
import ChinaLocation from 'china-location';
//提供獲取地址,修改地址API的類
//in node.js
//const ChinaLocation = require('china-location');

//初始化實例,並傳入json數據
const location = new ChinaLocation(list);

//獲取初始時當前地址包括code及中文名
//{
// province: {code: '110000', name: '北京市'},
// city: {code: '110000', name: '北京市'},
// district: {code: '110101', name: '東城區'}
//}
const defaultLocation = location.getCurrentAddress();

//修改地址
const newProvince = '320000';
const newCity = '320500';
const newDistrict = '320509';
//通常使用聯動下拉框,獲取選中的code來更新地址,得到下一級的數據
location.changeProvince(newProvince);
location.changeCity(newCity);
location.changeDistrict(newDistrict);
//也能夠一次性都修改
location.changeLocation(newProvince, newCity, newDistrict);
//{
// province: {code: '320000', name: '江蘇省'},
// city: {code: '320500', name: '蘇州市'},
// district: {code: '320509', name: '吳江區'}
//}
//獲取更新後的地址信息
const newLocation = location.getCurrentAddress();
複製代碼

API很簡單,初始化,而後修改當前地址,最後獲取當前地址。有了這樣的庫,咱們就能夠很方便的在瀏覽器頁面,或者在node.js端很容易的去作跟地址相關的邏輯🎉。git

使用本身build出來的地址數據

china-location打包進的數據可能不是最新的,可是原始數據可能已經更新過,爲了能不重複發佈版本,也能使用最新的數據,china-location也提供了簡單的npm script來轉換本地自定義的原始數據,而後再new ChinaLocation(latestData)初始化的時候傳入本身手動轉換的json數據。 首先clone原始數據repo:mumuy/data_location, 或者直接把裏面的list.json保存下來,而後git clone china-location:github

git clone git@github.com:JasonBoy/china-location.git
cd china-location
複製代碼

進入chian-location根目錄後使用reformatscript來轉換:npm

npm run reformat -- /path/to/data_location/list.json
複製代碼

--後面跟的參數就是原始數據的本地路徑,成功之後會輸出到dist目錄,裏面的location.jsonlocation.min.json, 而後直接拷到你的項目中import,傳到new ChinaLocation(data)構造函數便可使用最新的數據了。json

一個簡單的React組件

以上是純JS的使用,固然若是咱們的開發用一些UI庫的話,好比React, 我也寫了個簡單的React組件react-china-location, 樣式都是html原生的下拉框樣式,這裏只作一個demo使用,你能夠根據這個邏輯作出符合項目UI要求的組件:

react-china-location裏面的china-location是放在peerDependences中的,因此china-location也須要單獨安裝:

npm install china-location react-china-location --save
複製代碼

而後在你的JSX中:

import locationData from 'china-location/dist/location.json';
import ChinaLocation from 'react-china-location';

class App extends React.Component {
  constructor (props) {
    super(props);

    this.onLocationChange = this.onLocationChange.bind(this);
    this.state = {
      currentLocation: {},
    }
  }

  onLocationChange (newLocation) {
    //{
    // province: {code: '110000', name: '北京市'},
    // city: {code: '110000', name: '北京市'},
    // district: {code: '110101', name: '東城區'}
    //}
    console.log(newLocation);
    //更新到state
    this.setState({
      currentLocation: newLocation,
    });
  }

  render () {
    <div>
      <ChinaLocation list={locationData} onLocationChange={this.onLocationChange}/> </div>
  }
}
複製代碼

<ChinaLocation>組件裏的list prop就是轉換後的json數據, 而onLocationChange回調是當用戶選擇不一樣的省市區時的回調,會傳入最新的location數據,而後就能夠setState更新到頁面的其餘UI上。

結論

但願這個簡單的china-location庫能給其餘的小夥伴在項目中使用到地址邏輯的時候帶來方便,作到開箱即用,而無需浪費時間本身手動再寫一遍, 把更多的時間專一在本身業務邏輯上。

相關文章
相關標籤/搜索