Open-source project
TerryZ/v-region avatar
TerryZ/v-region

v-region: a four-level Chinese administrative division selector for Vue

提供 5 种应用形式的 4 级行政区划选择器 A simple region cascade selector, provide 4 levels Chinese administrative division data

944 stars152 forksTypeScriptMIT

At a glance

What is it?
v-region is a Vue 3 component library that lets users pick province, city, district and town from Chinese administrative division data, and offers the same data through five different interaction forms, from cascading dropdowns to a city picker.
Who is it for?
v-region is worth adopting if you are building a Vue 3 application that needs a Chinese address picker and do not want to ship and maintain your own division dataset, and the choice of five interaction forms means it can drop into a modal, a drawer or a plain inline field.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 19 days ago.
What is it written in?
Mainly TypeScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on November 7, 2026, and from our analysis. They are not legal advice.

From daily snapshots

Star history

  • TerryZ/v-region944 ★ · +1
Star history
Repository2026-10-222026-11-07
TerryZ/v-region943944

1 Stars in the last 16 days, measured from the daily GitHub snapshot. Compare with other projects

Editorial analysis

Four levels of Chinese administrative division, as a cascade

v-region is a region cascade selector that provides four levels of Chinese administrative division data: province or direct-administered municipality, city, district or county, and town, township or street.

The interaction is the familiar one. Choosing a province narrows the city list, choosing a city narrows the district list, and choosing a district narrows the town list. What the library adds is the data itself, which is the tedious part. The value objects are administrative codes rather than free text, so a form field can bind to a stable identifier instead of a string a user typed.

The example in the documentation shows the shape of the binding, with a `v-model` carrying an object of codes for all four levels:

vue
<template>
  <RegionSelects
    v-model="region"
    @change="change"
  />
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { RegionSelects } from 'v-region'
import type { RegionValues, RegionModel } from 'v-region'

const region = ref<RegionValues>({
  province: '350000',
  city: '350100',
  area: '350104',
  town: '350104008'
})
function change (data: RegionModel) {
  console.log(data)
}
</script>

The `RegionValues` and `RegionModel` types are exported from the package, so a TypeScript project gets the shape of the bound value without declaring it by hand.

The intended user is a Vue developer building a Chinese-market form where an address must be structured rather than typed. The package is published on npm as `v-region`, and the repository topics are region-selector, citypicker and vue3.

Five ways to present the same data

The library's most unusual feature is that it does not pick one interaction model for you. It ships five components, all fed by the same data, and the documentation names them explicitly.

`RegionSelects` is the cascading dropdown mode. `RegionGroup` is the grouped mode. `RegionColumns` is the multi-column vertical layout. `RegionCityPicker` is a city picker mode, the familiar search-a-city-then-drill pattern. `RegionText` is a plain text mode.

The composition rule is what makes this more than a menu of widgets. The grouped and column modes are built on the core modules `RegionGroup` and `RegionColumns`, so they can be combined with other interaction forms, and the documentation gives the examples: pairing them with a drawer, a popover or a dialog. In other words, the same cascade can live in a dropdown, in a side panel, or in a modal without being reimplemented.

Two smaller capabilities come with this. Some modes accept scoped slots so the trigger element can be customised, which is what lets the control look like your own button instead of a default input. And the administrative levels other than province can be switched through parameters, so you can offer two levels to one form and four levels to another without shipping two libraries.

The `examples/` directory in the repository mirrors this structure, with separate files for the city picker, columns, group, selects and text variants, which is the fastest way to see which mode suits your layout.

The awkward administrative cases are handled explicitly

Chinese administrative geography does not fit a neat four-column tree, and the library spends a feature bullet on the exceptions. The documentation lists support for direct-administered municipalities, special administrative regions, "directly administered cities" and province-administered counties and county-level cities, and describes both the data and the content handling for those cases.

This matters more than it sounds. A generic tree widget renders an exception as a broken branch: a municipality has no city level, a special administrative region has a different structure, and a county administered directly by a province skips a level. Handling them at the data layer means the component does not emit a value with a gap in it.

The second decision is about payload size. The documentation states that the 3rd and 4th level administrative components, which carry the larger data volumes, are split into separate modules that are used on demand. Since a four-level cascade pulls in every town and street name in the dataset, and most forms only need province, city and district, this split is what keeps the bundle reasonable.

So the architecture is: a core with the smaller levels, separate modules for the heavy ones, and per-mode components over the top. A project that needs only the upper levels can leave the lower modules out of its dependency graph entirely.

The dataset is current for three levels and dated for the fourth

This is the part to read carefully before you commit, because the data has two different ages.

The data comes from the `mumuy/data_location` repository. The upstream notes, quoted in the library's documentation, say that the province, city and district data comes from the civil affairs ministry, State Council announcements and the National Bureau of Statistics, and is kept up to date and authoritative. The library tracks a data version date, and the current one is 2026-08-30, matching the `dataVersion` field in the package manifest.

The street, town and township data is a different story. The upstream notes state that because the volume of data is enormous and there are many local government letters and announcements at every level, timely and valid data cannot be guaranteed, and give the latest data as 2016-07-31.

That is a decade-old snapshot for the fourth level, and it is the honest limit of this library. Provincial, city and district codes are current. Town and street codes may be renamed, merged or created since 2016, and a form that stores a town code as durable data is storing something that may no longer exist. The upstream notes also say that the data is organised by administrative district, and that administrative management districts, such as special economic zones, development zones, high-tech zones, new districts and industrial zones, overlap with administrative districts and are therefore not included, with some cases promoted to administrative districts and needing to be distinguished.

If your product needs a town-level code that stays valid for years, treat the fourth level as a display convenience rather than a key.

Installing and using the components in a Vue 3 app

Installation is a normal package install, and the documentation lists the three package managers:

bash
# npm
npm i v-region
# yarn
yarn add v-region
# pnpm
pnpm add v-region

The package is an ES module with a CommonJS build alongside it. The manifest sets `main` to `./dist/v-region.cjs`, `module` to `./dist/v-region.js` and the `exports` map points each condition at the matching file with TypeScript declarations at `./dist/types/index.d.ts`.

To register every mode globally:

js
import { createApp } from 'vue'
import App from './app.vue'
import Region from 'v-region'
createApp(App).use(Region).mount('#app')

Or to register only the component you need, which keeps the rest of the modules out of your app:

js
import { RegionSelects } from 'v-region'

const app = createApp(App)
app.component('v-region-selects', RegionSelects)

One constraint is worth checking early. The manifest lists vue at `^3.5.39` as a peer dependency, and the README states that projects still on Vue 2.x should use the separate v-region 2.x branch. The library is built with Vite and Vue 3, so the Vue 2 path is a fork of the project rather than a compatibility mode.

Runtime dependencies are minimal: `vue` and `v-dropdown`, the dropdown primitive the cascade is built on.

A Vue 3 package with a modern toolchain behind it

The repository is a modern Vue 3 workspace, and the toolchain tells you how the project is maintained. It uses pnpm, with a `pnpm-lock.yaml` and a `pnpm-workspace.yaml`, and the manifest pins the package manager to `[email protected]`.

Quality tooling is split between oxlint and ESLint, with the lint script running both: `oxlint . --fix` and `eslint . --fix --cache`. Formatting is Prettier through `prettier --write --experimental-cli src/`, and there is a separate `dts` script that emits declaration files with `vue-tsc --declaration --emitDeclarationOnly`, which is what produces the `dist/types` output that consumers import.

Tests run on Vitest, with `test:unit` for the watch mode and `coverage` for `vitest run --coverage`. The repository carries `vitest.config.ts` and a separate `tsconfig.vitest.json`, and the README links a code coverage badge, so coverage is tracked rather than assumed.

The default branch is `dev`, while the published npm workflow badge points at the `master` branch, and there are two changelogs, `CHANGELOG.md` and `CHANGELOG-CN.md`, which is a small signal that the maintainer serves both an international and a Chinese-language audience.

On versions, the manifest reads 3.6.1, matching the tagged v3.6.1 release dated 2026-08-30, alongside v3.6.0 the same day and v3.5.2 from 2026-04-02. Two releases in one day usually means a fix landing quickly after a feature, so if you are on 3.6.0, the patch release is worth taking.

The licence is MIT, the `license` field in the manifest and the LICENSE file at the repository root agree, and the README carries a FOSSA badge for licence scanning.

Editorial conclusion

v-region is worth adopting if you are building a Vue 3 application that needs a Chinese address picker and do not want to ship and maintain your own division dataset, and the choice of five interaction forms means it can drop into a modal, a drawer or a plain inline field. It is the wrong choice for a Vue 2 codebase, where the README points to a separate 2.x branch, and it is the wrong choice if you need accurate town and street level data, since the underlying data source documents its street level data as dating from 2016-07-31. Before adopting, check the data version, which the manifest records as 2026-08-30, against the levels you need, and confirm that a v3.6.1 build supports your Vue version, since the package asks for vue ^3.5.39 as a peer dependency.

Frequently asked questions

How do I install v-region?

Install it like any npm package, with npm i v-region, yarn add v-region or pnpm add v-region. The package ships an ES module build, a CommonJS build and TypeScript declarations.

What administrative levels does v-region support?

Four levels: province or direct-administered municipality, city, district or county, and town, township or street. The levels other than province can be switched through parameters, and the third and fourth level components are split into separate modules so they are only loaded when needed.

Can I use v-region with Vue 2?

Not from this version. The package asks for vue ^3.5.39 as a peer dependency, and the README directs projects on Vue 2.x to the separate v-region 2.x branch.

How fresh is the administrative division data?

The manifest records a data version of 2026-08-30, and the upstream notes say province, city and district data comes from official announcements and statistics. The same notes say the town, township and street data cannot be guaranteed to be timely, with the latest dated 2016-07-31.

What interaction styles does v-region provide?

Five: the cascading dropdown mode RegionSelects, the grouped mode RegionGroup, the multi-column mode RegionColumns, the city picker mode RegionCityPicker and the plain text mode RegionText. The grouped and column modes can be combined with a drawer, a popover or a dialog.

Official sources

  1. License: MIT
  2. Project website
  3. README
  4. Releases
  5. TerryZ/v-region on GitHub
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/terryz-v-region.svg)](https://hysenlabs.com/projects/terryz-v-region)

Star history chart for your README

markdown
[![Star history](https://hysenlabs.com/chart/terryz-v-region.svg)](https://hysenlabs.com/projects/terryz-v-region)

Was this useful?