说明
其实该组件很简单,核心在于全国省市区数据的来源,还有数据格式化以及组件封装。
然后大家应该知道在vue2阶段其实有一个省市区的第三方封装的组件,我想大家应该不少人使用过。
看源码,作者应该暂时没有发布vue3的计划。那么我这里就提前一步给大家个福利。
使用的话直接看使用部分就行了。
核心原理
数据基于:github.com/airyland/ch…
根据第三方提供的省市区数据部分,将数据改为element-plus所需的嵌套数据结构
封装ChinaArea类函数
chinaObj将第三方数据改平为一个大对象,可以根据value值进行取值。数据提前赋值给chinaAreaflat
recursion递归函数,支持了增加全部选项(isall)还有控制递归层级leave参数
最终导出得到
chinaAreaData原始数据
ChinaAreaflat改平为对象的数据
关于组件选择之后参数取值问题:
import { EluiChinaAreaDht } from 'elui-china-area-dht'
const chinaData = new EluiChinaAreaDht.ChinaArea().chinaAreaflat
chinaData[得到的value值]
jsx代码
采用高阶函数形式封装,最大限度的保留el-cascader参数的完整性,也就是说除了options参数所有原el-cascader参数都可以使用
import { defineComponent, ref } from 'vue'
import ChinaArea from './ChinaArea'
const EluiChinaAreaDht = defineComponent({
name: 'EluiChinaAreaDht',
props: {
isall: Boolean,
leave: {
type: Number,
default: 3,
},
},
setup(props, ctx) {
const chinaArea = new ChinaArea({ leave: props.leave, isall: props.isall })
const options = ref(chinaArea.chinaData())
return () => <el-cascader {...ctx.attrs} options={options.value} v-slots={ctx.slots} />
},
})
export default EluiChinaAreaDht
ts代码部分
import chinaAreaData from 'china-area-data'
// 递归子选项
interface Options {
label: string
value: string
leave?: number
children?: Options[]
}
// 省市区数据结构化定义类型
interface ChinaArr {
label: string
parent?: string
value: string
}
// 递归输入参数
interface InRecursion {
ssq: { [key: string]: string }
leave?: number
custom?: Options
}
interface ChinaAreaInput {
leave: number
isall: boolean
customItem?: Options[]
after?: boolean
}
interface ChinaAreaflat {
[key: string]: ChinaArr
}
class ChinaArea {
chinaAreaData = chinaAreaData
chinaAreaflat: ChinaAreaflat // 对象改平之后的结构,用于数据取值
// 将数组结构转化为对象结构
chinaObj() {
const list: ChinaAreaflat = {}
for (const key in chinaAreaData) {
for (const i in chinaAreaData[key]) {
const item: ChinaArr = {
label: chinaAreaData[key][i],
value: i,
}
if (key !== '86') item.parent = key
list[i] = item
}
}
return list
}
leave = 3 // 控制递归层级
isall = false // 是否需要全部选项
constructor({ leave = 0, isall = false }: ChinaAreaInput = {} as ChinaAreaInput) {
this.leave = leave
this.isall = isall
this.chinaAreaflat = this.chinaObj()
}
// 省市区数据格式化
chinaData() {
const province = chinaAreaData[86]
const opt: InRecursion = { ssq: province }
if (this.isall) {
opt.custom = {
label: '全部',
value: 'all',
}
}
return this.recursion(opt)
}
// 递归得到省市区三级数据
private recursion({
ssq,
leave = 0, // 这个不是外部操作的,不允许修改
custom,
}: InRecursion) {
const layer = leave + 1
if (layer > this.leave) return
const reprovince = []
custom && reprovince.push(custom)
for (const i in ssq) {
const item: Options = {
label: ssq[i],
value: i,
leave: layer,
}
if (chinaAreaData[i]) {
item.children = this.recursion({ ssq: chinaAreaData[i], leave: layer, custom })
}
reprovince.push(item)
}
return reprovince
}
}
export default ChinaArea
使用
npm地址:https://www.npmjs.com/package/elui-china-area-dht
git地址:https://github.com/ht-sauce/elui-china-area-dht
语雀说明文档地址:https://www.yuque.com/cv8igf/gaxplg/btzy5i
npm i elui-china-area-dht
代码部分
<template>
<div class="app">
<!--默认使用-->
<elui-china-area-dht @change="onChange"></elui-china-area-dht>
<!--带isall参数和leave参数示例-->
<elui-china-area-dht isall :leave="2" @change="onChange"></elui-china-area-dht>
</div>
</template>
<script>
import { defineComponent } from 'vue'
import { EluiChinaAreaDht } from 'elui-china-area-dht'
const chinaData = new EluiChinaAreaDht.ChinaArea().chinaAreaflat
export default defineComponent({
components: {
EluiChinaAreaDht,
},
setup() {
function onChange(e) {
const one = chinaData[e[0]]
const two = chinaData[e[1]]
console.log(one, two)
}
return {
onChange,
}
},
})
</script>
致谢
element-plus
vue
数据来源:https://github.com/airyland/china-area-data
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!