|
@@ -0,0 +1,159 @@
|
|
|
+<template>
|
|
|
+ <el-cascader
|
|
|
+ ref="cascader"
|
|
|
+ v-model="selectedValues"
|
|
|
+ :options="options"
|
|
|
+ :props="cascaderProps"
|
|
|
+ :placeholder="placeholder"
|
|
|
+ :clearable="clearable"
|
|
|
+ :disabled="disabled"
|
|
|
+ :size="size"
|
|
|
+ @change="handleChange"
|
|
|
+ @expand-change="handleExpandChange"
|
|
|
+ filterable
|
|
|
+ />
|
|
|
+</template>
|
|
|
+
|
|
|
+<script>
|
|
|
+import { getLazyTree } from '@/api/base/region'
|
|
|
+
|
|
|
+export default {
|
|
|
+ name: 'RegionCascader',
|
|
|
+ props: {
|
|
|
+ value: {
|
|
|
+ type: [String, Array],
|
|
|
+ default: ''
|
|
|
+ },
|
|
|
+ placeholder: {
|
|
|
+ type: String,
|
|
|
+ default: '请选择省/市/区'
|
|
|
+ },
|
|
|
+ clearable: {
|
|
|
+ type: Boolean,
|
|
|
+ default: true
|
|
|
+ },
|
|
|
+ disabled: {
|
|
|
+ type: Boolean,
|
|
|
+ default: false
|
|
|
+ },
|
|
|
+ size: {
|
|
|
+ type: String,
|
|
|
+ default: 'small'
|
|
|
+ }
|
|
|
+ },
|
|
|
+ data() {
|
|
|
+ return {
|
|
|
+ options: [],
|
|
|
+ selectedValues: [],
|
|
|
+ cascaderProps: {
|
|
|
+ value: 'value',
|
|
|
+ label: 'title',
|
|
|
+ children: 'children',
|
|
|
+ lazy: true,
|
|
|
+ lazyLoad: this.lazyLoad,
|
|
|
+ checkStrictly: false
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ watch: {
|
|
|
+ value: {
|
|
|
+ handler(newVal) {
|
|
|
+ if (newVal && typeof newVal === 'string') {
|
|
|
+ this.selectedValues = []
|
|
|
+ } else if (Array.isArray(newVal)) {
|
|
|
+ this.selectedValues = [...newVal]
|
|
|
+ } else {
|
|
|
+ this.selectedValues = []
|
|
|
+ }
|
|
|
+ },
|
|
|
+ immediate: true
|
|
|
+ }
|
|
|
+ },
|
|
|
+ async mounted() {
|
|
|
+ await this.loadProvinces()
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ async loadProvinces() {
|
|
|
+ try {
|
|
|
+ const res = await getLazyTree('00')
|
|
|
+ if (res.data.success) {
|
|
|
+ this.options = res.data.data.map(item => ({
|
|
|
+ ...item,
|
|
|
+ leaf: false
|
|
|
+ }))
|
|
|
+ }
|
|
|
+ } catch (error) {
|
|
|
+ console.error('加载省级数据失败:', error)
|
|
|
+ this.$message.error('加载省级数据失败')
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ async lazyLoad(node, resolve) {
|
|
|
+ const { level, value } = node
|
|
|
+
|
|
|
+ try {
|
|
|
+ // 如果是第三级(区级),直接返回空数组,不再加载子级
|
|
|
+ if (level >= 3) {
|
|
|
+ resolve([])
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ const res = await getLazyTree(value)
|
|
|
+ if (res.data.success) {
|
|
|
+ const children = res.data.data.map(item => ({
|
|
|
+ ...item,
|
|
|
+ leaf: level >= 2 // 市级的子级(区级)设为叶子节点
|
|
|
+ }))
|
|
|
+ resolve(children)
|
|
|
+ } else {
|
|
|
+ resolve([])
|
|
|
+ }
|
|
|
+ } catch (error) {
|
|
|
+ console.error('加载子级数据失败:', error)
|
|
|
+ resolve([])
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 选择改变事件
|
|
|
+ * @param {Array} values - 选中的值数组
|
|
|
+ */
|
|
|
+ handleChange(values) {
|
|
|
+ this.selectedValues = values || []
|
|
|
+
|
|
|
+ // 获取选中的节点信息
|
|
|
+ // const selectedNodes = this.$refs.cascader?.getCheckedNodes() || []
|
|
|
+ const selectedNodes = this.$refs.cascader ? this.$refs.cascader.getCheckedNodes() : []
|
|
|
+
|
|
|
+ let regionName = ''
|
|
|
+ let regionCode = ''
|
|
|
+
|
|
|
+ if (values && values.length > 0) {
|
|
|
+ // 获取选中的节点信息
|
|
|
+ const selectedNodes = this.$refs.cascader.getCheckedNodes()
|
|
|
+ if (selectedNodes.length > 0) {
|
|
|
+ const node = selectedNodes[0]
|
|
|
+ regionName = node.pathLabels.join(' ')
|
|
|
+ regionCode = values[values.length - 1]
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 直接返回regionName作为组件的值,这样avue-crud可以正确验证
|
|
|
+ this.$emit('input', regionName)
|
|
|
+ this.$emit('change', {
|
|
|
+ values,
|
|
|
+ regionName,
|
|
|
+ regionCode
|
|
|
+ })
|
|
|
+ },
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 展开改变事件
|
|
|
+ * @param {Array} activeValues - 当前展开的值
|
|
|
+ */
|
|
|
+ handleExpandChange(activeValues) {
|
|
|
+ this.$emit('expand-change', activeValues)
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+</script>
|