mirror of
https://github.com/pure-admin/vue-pure-admin.git
synced 2025-11-15 14:03:36 +08:00
feat: add area cascade selector demo (#257)
This commit is contained in:
@@ -53,7 +53,7 @@ const props = {
|
||||
};
|
||||
|
||||
export default defineComponent({
|
||||
name: "epTableProBar",
|
||||
name: "ReQrcode",
|
||||
props,
|
||||
emits: ["done", "click", "disabled-click"],
|
||||
setup(props, { emit }) {
|
||||
|
||||
@@ -113,10 +113,19 @@ const ableRouter = {
|
||||
},
|
||||
{
|
||||
path: "/able/qrcode",
|
||||
name: "reQarcode",
|
||||
name: "reQrcode",
|
||||
component: () => import("/@/views/able/qrcode.vue"),
|
||||
meta: {
|
||||
title: $t("menus.hsQarcode"),
|
||||
title: $t("menus.hsQrcode"),
|
||||
i18n: true
|
||||
}
|
||||
},
|
||||
{
|
||||
path: "/able/cascader",
|
||||
name: "reCascader",
|
||||
component: () => import("/@/views/able/cascader.vue"),
|
||||
meta: {
|
||||
title: $t("menus.hsCascader"),
|
||||
i18n: true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,6 +30,11 @@
|
||||
margin-left: $sideBarWidth;
|
||||
position: relative;
|
||||
background: #f0f2f5;
|
||||
|
||||
.el-scrollbar__wrap {
|
||||
overflow: auto;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.fixed-header {
|
||||
@@ -483,11 +488,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
.el-scrollbar__wrap {
|
||||
overflow: auto;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.el-menu--collapse .el-menu .el-sub-menu {
|
||||
min-width: $sideBarWidth !important;
|
||||
}
|
||||
|
||||
190
src/utils/chinaArea.ts
Normal file
190
src/utils/chinaArea.ts
Normal file
@@ -0,0 +1,190 @@
|
||||
import REGION_DATA from "china-area-data";
|
||||
import { cloneDeep } from "lodash-unified";
|
||||
|
||||
interface ProvinceData {
|
||||
value: string;
|
||||
label: string;
|
||||
children?: Array<ProvinceData>;
|
||||
}
|
||||
|
||||
// code转汉字大对象,例:CodeToText['110000']输出北京市
|
||||
const CodeToText = {};
|
||||
// 汉字转code大对象,例:TextToCode['北京市']['市辖区']['朝阳区'].code输出110105
|
||||
const TextToCode = {};
|
||||
// 省份对象
|
||||
const provinceObject = REGION_DATA["86"];
|
||||
// 省市区三级联动数据(不带“全部”选项)
|
||||
const regionData = [];
|
||||
// 省市二级联动数据(不带“全部”选项)
|
||||
let provinceAndCityData = [];
|
||||
|
||||
const ALL_TEXT = "全部";
|
||||
|
||||
CodeToText[""] = ALL_TEXT;
|
||||
|
||||
// 计算省
|
||||
Object.keys(provinceObject).forEach(prop => {
|
||||
const provinceText = provinceObject[prop];
|
||||
regionData.push({
|
||||
value: prop, // 省份code值
|
||||
label: provinceText // 省份汉字
|
||||
});
|
||||
CodeToText[prop] = provinceText;
|
||||
TextToCode[provinceText] = {
|
||||
code: prop
|
||||
};
|
||||
TextToCode[provinceText][ALL_TEXT] = {
|
||||
code: ""
|
||||
};
|
||||
});
|
||||
|
||||
// 计算市
|
||||
regionData.forEach((item: ProvinceData) => {
|
||||
const provinceCode = item.value;
|
||||
const provinceText = item.label;
|
||||
const provinceChildren = [];
|
||||
const provinceData = REGION_DATA[provinceCode] ?? {};
|
||||
|
||||
Object.keys(provinceData).forEach(prop => {
|
||||
provinceChildren.push({
|
||||
value: prop,
|
||||
label: provinceData[prop]
|
||||
});
|
||||
CodeToText[prop] = provinceData[prop];
|
||||
TextToCode[provinceText][provinceData[prop]] = {
|
||||
code: prop
|
||||
};
|
||||
TextToCode[provinceText][provinceData[prop]][ALL_TEXT] = {
|
||||
code: ""
|
||||
};
|
||||
});
|
||||
|
||||
if (provinceChildren.length) {
|
||||
item.children = provinceChildren;
|
||||
}
|
||||
});
|
||||
provinceAndCityData = cloneDeep(regionData);
|
||||
|
||||
// 计算区
|
||||
regionData.forEach((item: ProvinceData) => {
|
||||
const province = item.children;
|
||||
const provinceText = item.label;
|
||||
|
||||
if (province) {
|
||||
province.forEach(pItem => {
|
||||
const cityCode = pItem.value;
|
||||
const cityText = pItem.label;
|
||||
const cityChildren = [];
|
||||
const cityData = REGION_DATA[cityCode] ?? {};
|
||||
|
||||
Object.keys(cityData).forEach(prop => {
|
||||
cityChildren.push({
|
||||
value: prop,
|
||||
label: cityData[prop]
|
||||
});
|
||||
CodeToText[prop] = cityData[prop];
|
||||
TextToCode[provinceText][cityText][cityData[prop]] = {
|
||||
code: prop
|
||||
};
|
||||
});
|
||||
|
||||
if (cityChildren.length) {
|
||||
pItem.children = cityChildren;
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// 添加“全部”选项
|
||||
const provinceAndCityDataPlus = cloneDeep(provinceAndCityData);
|
||||
provinceAndCityDataPlus.unshift({
|
||||
value: "",
|
||||
label: ALL_TEXT
|
||||
});
|
||||
provinceAndCityDataPlus.forEach((item: ProvinceData) => {
|
||||
const province = item.children;
|
||||
|
||||
if (province?.length) {
|
||||
province.unshift({
|
||||
value: "",
|
||||
label: ALL_TEXT
|
||||
});
|
||||
|
||||
province.forEach(pItem => {
|
||||
const city = pItem.children;
|
||||
|
||||
if (city?.length) {
|
||||
city.unshift({
|
||||
value: "",
|
||||
label: ALL_TEXT
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
const regionDataPlus = cloneDeep(regionData);
|
||||
regionDataPlus.unshift({
|
||||
value: "",
|
||||
label: ALL_TEXT
|
||||
});
|
||||
regionDataPlus.forEach((item: ProvinceData) => {
|
||||
const province = item.children;
|
||||
|
||||
if (province?.length) {
|
||||
province.unshift({
|
||||
value: "",
|
||||
label: ALL_TEXT
|
||||
});
|
||||
province.forEach(pItem => {
|
||||
const city = pItem.children;
|
||||
|
||||
if (city?.length) {
|
||||
city.unshift({
|
||||
value: "",
|
||||
label: ALL_TEXT
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* 汉字转区域码
|
||||
* @param provinceText 省
|
||||
* @param cityText 市
|
||||
* @param regionText 区
|
||||
* @returns
|
||||
*/
|
||||
function convertTextToCode(
|
||||
provinceText: string,
|
||||
cityText: string,
|
||||
regionText?: string
|
||||
): string {
|
||||
let code = "";
|
||||
if (provinceText && TextToCode[provinceText]) {
|
||||
const province = TextToCode[provinceText];
|
||||
code = province.code;
|
||||
|
||||
if (cityText && province[cityText]) {
|
||||
const city = province[cityText];
|
||||
code = `${code}${cityText === ALL_TEXT ? "" : ", "}${city.code}`;
|
||||
|
||||
if (regionText && city[regionText]) {
|
||||
code = `${code}${regionText === ALL_TEXT ? "" : ", "}${
|
||||
city[regionText].code
|
||||
}`;
|
||||
}
|
||||
}
|
||||
}
|
||||
return code;
|
||||
}
|
||||
export {
|
||||
provinceAndCityData,
|
||||
regionData,
|
||||
provinceAndCityDataPlus,
|
||||
regionDataPlus,
|
||||
CodeToText,
|
||||
TextToCode,
|
||||
convertTextToCode
|
||||
};
|
||||
148
src/views/able/cascader.vue
Normal file
148
src/views/able/cascader.vue
Normal file
@@ -0,0 +1,148 @@
|
||||
<script setup lang="ts">
|
||||
import {
|
||||
provinceAndCityDataPlus,
|
||||
provinceAndCityData,
|
||||
convertTextToCode,
|
||||
regionDataPlus,
|
||||
regionData,
|
||||
CodeToText
|
||||
} from "/@/utils/chinaArea";
|
||||
import { ref } from "vue";
|
||||
|
||||
const selectedOptions1 = ref(["110000", "110100"]);
|
||||
const selectedOptions2 = ref(["120000", "120100", "120101"]);
|
||||
const selectedOptions3 = ref(["130000", ""]);
|
||||
const selectedOptions4 = ref(["120000", "120100", ""]);
|
||||
|
||||
const handleChange = value => {
|
||||
console.log(value);
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<el-card>
|
||||
<template #header> 区域级联选择器 </template>
|
||||
<el-row :gutter="20">
|
||||
<el-col :xl="12" :lg="12" :md="24" :sm="24" :xs="24">
|
||||
<div class="flex flex-col items-center justify-center">
|
||||
<span class="imp">
|
||||
1. 二级联动(不带“全部”选项)
|
||||
<el-cascader
|
||||
:options="provinceAndCityData"
|
||||
v-model="selectedOptions1"
|
||||
@change="handleChange"
|
||||
/>
|
||||
</span>
|
||||
<div class="leading-10">
|
||||
<div>绑定值:{{ selectedOptions1 }}</div>
|
||||
<div>
|
||||
区域码转汉字:{{ CodeToText[selectedOptions1[0]] }},{{
|
||||
CodeToText[selectedOptions1[1]]
|
||||
}}
|
||||
</div>
|
||||
<div>
|
||||
汉字转区域码:{{
|
||||
convertTextToCode(
|
||||
CodeToText[selectedOptions1[0]],
|
||||
CodeToText[selectedOptions1[1]]
|
||||
)
|
||||
}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :xl="12" :lg="12" :md="24" :sm="24" :xs="24">
|
||||
<div class="flex flex-col items-center justify-center mt-3">
|
||||
<span class="imp">
|
||||
2. 二级联动(带有“全部”选项)
|
||||
<el-cascader
|
||||
:options="provinceAndCityDataPlus"
|
||||
v-model="selectedOptions3"
|
||||
@change="handleChange"
|
||||
/>
|
||||
</span>
|
||||
<div class="leading-10">
|
||||
<div>绑定值:{{ selectedOptions3 }}</div>
|
||||
<div>
|
||||
区域码转汉字:{{ CodeToText[selectedOptions3[0]] }},{{
|
||||
CodeToText[selectedOptions3[1]]
|
||||
}}
|
||||
</div>
|
||||
<div>
|
||||
汉字转区域码:{{
|
||||
convertTextToCode(
|
||||
CodeToText[selectedOptions3[0]],
|
||||
CodeToText[selectedOptions3[1]]
|
||||
)
|
||||
}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :xl="12" :lg="12" :md="24" :sm="24" :xs="24">
|
||||
<div class="flex flex-col items-center justify-center mt-3">
|
||||
<span class="imp">
|
||||
3. 三级联动(不带“全部”选项)
|
||||
<el-cascader
|
||||
:options="regionData"
|
||||
v-model="selectedOptions2"
|
||||
@change="handleChange"
|
||||
/>
|
||||
</span>
|
||||
<div class="leading-10">
|
||||
<div>绑定值:{{ selectedOptions2 }}</div>
|
||||
<div>
|
||||
区域码转汉字:{{ CodeToText[selectedOptions2[0]] }},{{
|
||||
CodeToText[selectedOptions2[1]]
|
||||
}},{{ CodeToText[selectedOptions2[2]] }}
|
||||
</div>
|
||||
<div>
|
||||
汉字转区域码:{{
|
||||
convertTextToCode(
|
||||
CodeToText[selectedOptions2[0]],
|
||||
CodeToText[selectedOptions2[1]],
|
||||
CodeToText[selectedOptions2[2]]
|
||||
)
|
||||
}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :xl="12" :lg="12" :md="24" :sm="24" :xs="24">
|
||||
<div class="flex flex-col items-center justify-center mt-3">
|
||||
<span class="imp">
|
||||
4. 三级联动(带"全部选项")
|
||||
<el-cascader
|
||||
:options="regionDataPlus"
|
||||
v-model="selectedOptions4"
|
||||
@change="handleChange"
|
||||
/>
|
||||
</span>
|
||||
<div class="leading-10">
|
||||
<div>绑定值:{{ selectedOptions4 }}</div>
|
||||
<div>
|
||||
区域码转汉字:{{ CodeToText[selectedOptions4[0]] }},{{
|
||||
CodeToText[selectedOptions4[1]]
|
||||
}},{{ CodeToText[selectedOptions4[2]] }}
|
||||
</div>
|
||||
<div>
|
||||
汉字转区域码:{{
|
||||
convertTextToCode(
|
||||
CodeToText[selectedOptions4[0]],
|
||||
CodeToText[selectedOptions4[1]],
|
||||
CodeToText[selectedOptions4[2]]
|
||||
)
|
||||
}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-card>
|
||||
</template>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.imp {
|
||||
color: var(--el-color-primary);
|
||||
}
|
||||
</style>
|
||||
@@ -116,7 +116,6 @@ const rules = {
|
||||
<el-select
|
||||
v-model="formData.type"
|
||||
clearable
|
||||
:teleported="false"
|
||||
:style="{ width: '480px' }"
|
||||
>
|
||||
<el-option
|
||||
|
||||
Reference in New Issue
Block a user