vue el-cascader 省市区封装及使用

使用了 Element UI 中的 el-cascader 组件,并对其进行了进一步封装和定制

创建组件index.vue (src/components/addressCascader/index.vue)
<template>
  <div>
    <el-cascader
        v-if="showca"
        size="large"
        :props="props"
        :options="cascaderOption"
        :placeholder="placeholder || '选择省/市/区'"
        v-model="selectedOptions"
        @change="addressChange"
        ref="place"
        :disabled="disabled"
        :clearable="clearable"
        :popper-class=" 'cascader-default'
      "
    >
    </el-cascader>
  </div>
</template>

<script>
  import { getDistrictAllSelect, getDistrictFilterSelect } from '@/api/district'
  export default {
    props: {
      selectedVal: {
        type: [Number, String],
        default: ''
      },
      disabled: {
        type: Boolean,
        default: false
      },
      checkStrictly: {
        type: Boolean,
        default: false
      },
      isNeedFilter: {
        type: Boolean,
        default: true
      },
      clearable: {
        type: Boolean,
        default: false
      },
      placeholder: String
    },
    data () {
      return {
        props: {
          value: 'id',
          label: 'name',
          checkStrictly: this.checkStrictly,
          expandTrigger: 'hover'
        },
        newDistictId: '',
        selectedOptions: [],
        showca: true,
        timeout: null,
        isChoose: false,
        chooseLevel: 0,
        cascaderOption: [],
        originData: [],
        cascaderList: []
      }
    },
    watch: {
      selectedVal: {
        handler (val) {
          if (val) {
            if(this.originData.length>0) {
              this.cascaderList = []
              this.findParent(Number(this.selectedVal))
              this.cascaderList.push(Number(this.selectedVal))
              this.selectedOptions = this.cascaderList
              this.$nextTick(() => {
                let label = this.$refs.place.getCheckedNodes()
                    ? this.$refs.place.getCheckedNodes()[0].pathLabels
                        ? this.$refs.place.getCheckedNodes()[0].pathLabels.join('')
                        : ''
                    : ''
                let level = this.$refs.place.getCheckedNodes()
                    ? this.$refs.place.getCheckedNodes()[0].level
                    : ''

                this.$emit(
                    'getVal',
                    this.selectedOptions[this.selectedOptions.length - 1],
                    label,
                    level
                )
              })
            }
          } else {
            this.clearVal()
          }
        },
        immediate: true
      }
    },
    mounted () {
      this.getDistrictAllSelect()
    },
    beforeDestroy () {},
    methods: {
      findParent (idx) {
        this.originData.forEach(item => {
          if (idx.toString() === item.id.toString()) {
            let pid = item['parentId']

            if (pid !== 0) {
              this.cascaderList.unshift(pid)
              this.findParent(pid)
            }
          }
        })
      },

      addressChange (arr) {
        if (arr.length > 1) {
          this.isChoose = true
        }
        if (arr.length == 1) {
          this.chooseLevel = 0
        } else if (arr.length == 2) {
          this.chooseLevel = 1
        } else if (arr.length == 3) {
          this.chooseLevel = 3
        }
        if (arr.length == 0) {
          this.$emit('getVal', '')
          return
        }
        console.log(
            this.$refs.place.getCheckedNodes()[0],
            'this.$refs.place.getCheckedNodes()[0]'
        )
        let label = this.$refs.place.getCheckedNodes()[0].pathLabels
            ? this.$refs.place.getCheckedNodes()[0].pathLabels.join('')
            : ''
        let level = this.$refs.place.getCheckedNodes()[0].level

        this.$emit('getVal', arr[arr.length - 1], label, level)
        if (arr.length > 2) {
          this.$refs.place.dropDownVisible = false
        }
      },
      clearVal () {
        if (this.$refs.place) {
          this.selectedOptions = []
          this.$refs.place.$refs.panel.checkedValue = []
          this.$refs.place.$refs.panel.activePath = []
          this.$refs.place.$refs.panel.syncActivePath()
        }
      },
      async getDistrictAllSelect () {

        let data
        if (this.checkStrictly && this.isNeedFilter) {
          data = await getDistrictFilterSelect()
          this.originData = data || []
          this.cascaderOption = this.transTree(data)
        } else {
          if (sessionStorage.pvRegionData&&sessionStorage.pvRegionOriginData!='undefined') {
            this.originData = JSON.parse(sessionStorage.pvRegionOriginData)
            this.cascaderOption = JSON.parse(sessionStorage.pvRegionData)
          } else {
            data = await getDistrictAllSelect()
            this.originData = data || []
            sessionStorage.setItem('pvRegionOriginData', JSON.stringify(data))
            this.cascaderOption = this.transTree(data)
            sessionStorage.setItem(
                'pvRegionData',
                JSON.stringify(this.cascaderOption)
            )
          }
        }
        if (this.selectedVal) {
          this.cascaderList = []
          this.findParent(Number(this.selectedVal))
          this.cascaderList.push(Number(this.selectedVal))
          this.selectedOptions = this.cascaderList
          this.$nextTick(() => {
            let label = this.$refs.place.getCheckedNodes()
                ? this.$refs.place.getCheckedNodes()[0].pathLabels
                    ? this.$refs.place.getCheckedNodes()[0].pathLabels.join('')
                    : ''
                : ''
            let level = this.$refs.place.getCheckedNodes()
                ? this.$refs.place.getCheckedNodes()[0].level
                : ''

            this.$emit(
                'getVal',
                this.selectedOptions[this.selectedOptions.length - 1],
                label,
                level
            )
          })
        }
      },
      transTree (data) {
        let result = []
        let map = {}
        if (!Array.isArray(data)) {
          //验证data是不是数组类型
          return []
        }
        data.forEach(item => {
          //建立每个数组元素id和该对象的关系
          map[item.id] = item //这里可以理解为浅拷贝,共享引用
        })
        data.forEach(item => {
          let parent = map[item.parentId] //找到data中每一项item的爸爸
          if (parent) {
            //说明元素有爸爸,把元素放在爸爸的children下面
            ;(parent.children || (parent.children = [])).push(item)
          } else {
            //说明元素没有爸爸,是根节点,把节点push到最终结果中
            result.push(item) //item是对象的引用
          }
        })
        return result //数组里的对象和data是共享的
      }
    }
  }
</script>

<style scoped lang="scss"></style>





页面引入
  • 在需要使用addressCascader组件的地方,通过import语句引入组件注册并使用

<template>
  <div>
    <address-cascader
        :selectedVal="selectedValue"
        @getVal="
              (districtVal, districtLabel, districtLevel) =>
                setDistrictId(districtVal, districtLabel, info, districtLevel)
            "
        :isNeedFilter="info.isNeedFilter"
        :checkStrictly="info.checkStrictly"
        ref="addressCascader"
        :disabled="info.disabled"
    ></address-cascader>
  </div>
</template>
<script>
  import addressCascader from "@/components/addressCascader/index";

  export default {
    components: {
      addressCascader
    },
    data() {
      return {
        info:{
          clearable: true,
          isNeedFilter:false,
          valueFormat:'yyyy-MM-dd',
          checkStrictly: false,
          pickerOptions:{}
        },
        dataSource: [],
        selectedValue: ''
      }
    },
    methods: {
      setDistrictId(val, label, info, districtLevel) {
        console.log("选中的值,文字,信息,级别", val, label, info, districtLevel);
      }
    }
    // ...
  }
</script>

确保你已经安装了Vue.js和Element UI,并在项目中引入它们。

  • 8
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要在Vue3中使用el-cascader组件实现省市区的功能,你可以按照以下步骤进行操作: 1. 首先,在你的Vue组件中引入el-cascader组件和相关的样式。确保你已经正确安装了element-ui库。 2. 在data选项中定义一个数组来存储省市区的选项数据,例如`options`。 3. 在mounted或created钩子函数中,调用接口获取省份的数据,将返回的数据赋值给`options`数组。 4. 在el-cascader组件中使用`options`数组作为选项数据源,同时绑定一个`selectedOptions`属性作为双向绑定的值。 5. 在el-form-item中使用el-cascader组件,并设置相应的label和size属性。 6. 在el-cascader的change事件中,添加一个监听方法`handleChange`来处理选中值的变化。 7. 在`handleChange`方法中,可以根据选中的省份编码来调用接口获取对应的地市数据,并更新`options`数组。 8. 如果需要在页面上显示已选择的省市区,可以通过userInfo对象中的省市区编码来获取对应的文字描述,然后在el-form-item中进行展示。 下面是一个示例代码,帮助你更好地理解如何在Vue3中使用el-cascader组件实现省市区的功能: ```javascript <template> <el-form-item :label="$t('common.location')"> <el-cascader v-if="!isShowEdit" size="large" class="profile-cascader" :options="options" v-model="selectedOptions" @change="handleChange" /> <div v-else> {{ CodeToText }} / {{ CodeToText }} / {{ CodeToText }} </div> </el-form-item> </template> <script> import { ref, onMounted } from 'vue'; import { reqSelectArea } from '@/api'; // 假设这是一个获取地区数据的接口 export default { data() { return { options: [], // 存储省市区选项数据的数组 selectedOptions: [], // 保存已选中的省市区值的数组 }; }, async mounted() { await this.queryProvice(); }, methods: { async queryProvice() { const data = { areaCode: 0, level: 1 }; const res = await reqSelectArea(data); try { this.options = res.result; // 获取到的省份数据 } catch (error) {} }, async queryPrefectural(provinceCodes) { const data = { areaCode: provinceCodes

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值