省市联动
架构
bash
├── src
│ ├── components
│ │ ├── chooseArea
│ │ │ ├── lib (引入的第三方库)
│ │ │ │ └── xxx.json
│ │ │ ├── src (源码)
│ │ │ │ ├── index.vue
│ │ │ ├── index.ts
index.ts
ts
import { type App } from 'vue'
import chooseArea from './src/index.vue'
// 让这个组件可以通过use的形式使用
export default {
install(app: App) {
app.component('YJ-choose-area', chooseArea)
}
}
interface/chooseArea/type.ts
ts
export interface ChooseAreaType {
code: string
name: string
}
hooks/choosearea/useChoosearea.ts
ts
import { ref, onMounted, computed, watchEffect, watch } from 'vue'
import data from '@/components/chooseArea/lib/pca-code.json'
import { type ChooseAreaType } from '@/interfaces/chooseArea/type.ts'
export const useChoosearea = () => {
// 省份
const worldvalue = ref('')
// 市
const cityvalue = ref('')
// 区
const streetvalue = ref('')
// 省市区list
const worldoptions = ref<ChooseAreaType[]>([])
// 获取区list
const cityoptions = ref<ChooseAreaType[]>([])
// 获取streetlist
const streetoptions = ref<ChooseAreaType[]>([])
// 获取市list
const getworldoptions = () => {
let result: ChooseAreaType[] = []
data.forEach(item => {
let obj = {
code: item.code,
name: item.name
}
result.push(obj)
})
worldoptions.value = result
}
// 获取区list
const getcityoptions = () => {
let result: ChooseAreaType[] = []
data.forEach(item => {
if (item.name === worldvalue.value) {
item.children.forEach(item => {
let obj = {
code: item.code,
name: item.name
}
result.push(obj)
})
}
})
cityoptions.value = result
}
// 获取街道list
// 定义一个函数,用于获取街道选项
const getstreetoptions = () => {
// 定义一个空数组,用于存储街道选项
let result: ChooseAreaType[] = []
// 遍历data数组
data.forEach(item => {
// 如果当前项的name属性等于worldvalue.value
if (item.name === worldvalue.value) {
// 遍历当前项的children数组
item.children.forEach(item => {
// 如果当前项的name属性等于cityvalue.value
if (item.name === cityvalue.value) {
// 遍历当前项的children数组
item.children.forEach(item => {
// 定义一个对象,用于存储街道选项的code和name属性
let obj = {
code: item.code,
name: item.name
}
// 将对象添加到result数组中
result.push(obj)
})
}
})
}
})
// 将result数组赋值给streetoptions.value
streetoptions.value = result
}
// 监听省份变化
watch(
() => worldvalue.value,
(newval, oldval) => {
if (newval != oldval) {
cityvalue.value = ''
streetvalue.value = ''
getcityoptions()
getstreetoptions()
}
}
)
// 监听城市变化
watch(
() => cityvalue.value,
(newval, oldval) => {
if (newval != oldval) {
streetvalue.value = ''
getstreetoptions()
}
}
)
// 挂载 筛选出省份
onMounted(() => {
getworldoptions()
})
return {
worldvalue,
cityvalue,
streetvalue,
worldoptions,
cityoptions,
streetoptions
}
}
src/index.vue
vue
<template>
<div>
<el-select
filterable
v-model="worldvalue"
clearable
placeholder="请选择省"
style="width: 240px; margin-right: 20px"
>
<el-option v-for="item in worldoptions" :key="item.code" :label="item.name" :value="item.name" />
</el-select>
<el-select
filterable
v-model="cityvalue"
clearable
placeholder="请选择市"
style="width: 240px; margin-right: 20px"
>
<el-option v-for="item in cityoptions" :key="item.code" :label="item.name" :value="item.name" />
</el-select>
<el-select
filterable
v-model="streetvalue"
clearable
placeholder="请选择区"
style="width: 240px; margin-right: 20px"
>
<el-option v-for="item in streetoptions" :key="item.code" :label="item.name" :value="item.name" />
</el-select>
</div>
</template>
<script setup lang="ts">
import { useChoosearea } from '@/hooks/choosearea/useChoosearea.ts'
const { worldoptions, worldvalue, cityoptions, cityvalue, streetoptions, streetvalue } = useChoosearea()
</script>
<style scoped></style>
父元素调用
vue
<template>
<div>
<YJ-choose-area></YJ-choose-area>
</div>
</template>
<script setup lang="ts"></script>
<style scoped></style>