Vue实现省市区信息选择(附前端源码)

x33g5p2x  于2021-12-30 转载在 Vue.js  
字(4.8k)|赞(0)|评价(0)|浏览(1270)

一、背景

  • 在电商平台中一般会有更新用户个人信息的模块(见下图),在这个功能中,系统会要求用户填写省市区信息及详细地址,便于订单的准确配送。本文将通过Vue+SpringBoot来具体实现用户所在省市区信息的选择与保存。

二、Cascader 级联选择器

  • 用户在选择省市区时,一般会选择省,再选择地市,最后选择区或县市。对于这种数据集合有清晰的层级结构,可以通过级联选择器逐级查看并选择。
  • 我们直接使用Element-UI Cascader 级联选择器:

<el-cascader :options="options" clearable></el-cascader>

<script>
  export default {
    data() {
      return {
        options: [{
          value: 'zhinan',
          label: '指南',
          children: [{
            value: 'shejiyuanze',
            label: '设计原则',
            children: [{
              value: 'yizhi',
              label: '一致'
            }, {
              value: 'fankui',
              label: '反馈'
            }, {
              value: 'xiaolv',
              label: '效率'
            }, {
              value: 'kekong',
              label: '可控'
            }]
          }
          ...
        }]
      }
    }
  }
</script>

三、element-china-area-data省市区级联数据

  • 有了级联选择器这个操作的控件,还要为级联选择器中填充省市区的数据,这里我们引入element-china-area-data组件,该组件可以为Cascader级联选择器提供国内省市区三级、二级联动的数据。
  • 参考用法如下:
<template>
  <div id="app">
    <el-cascader
      size="large"
      :options="options"
      v-model="selectedOptions"
      @change="handleChange">
    </el-cascader>
  </div>
</template>

<script>
  import { regionData } from 'element-china-area-data'
  export default {
    data () {
      return {
        options: regionData,
        selectedOptions: []
      }
    },

    methods: {
      handleChange (value) {
        console.log(value)
      }
    }
  }
</script>

四、前端页面增加省市选择

  • 有了级联选择器及数据,接下来就可以把省市区选择的操作嵌入到用户更信信息模块中了:
<template>
  <div class="app-container">
    <el-row :gutter="20">
      <el-col :xs="24" :sm="24" :md="13" :lg="14" :xl="15">
        <!--    用户资料更新    -->
        <el-card class="box-card">
          <el-tabs v-model="activeName">
            <el-tab-pane label="资料更新" name="first">
              <el-form
                ref="form"
                :model="form"
                :rules="rules"
                style="margin-top: 10px"
                size="small"
                label-width="65px"
              >
                <el-form-item label="昵称" prop="nickName">
                  <el-input v-model="form.nickName" style="width: 35%" />
                  <span
                    style="color: #c0c0c0; margin-left: 10px"
                  >用户昵称不作为登录使用</span>
                </el-form-item>
                <el-form-item label="电话" prop="phone">
                  <el-input v-model="form.phone" style="width: 35%" />
                  <span
                    style="color: #c0c0c0; margin-left: 10px"
                  >电话号码不能重复</span>
                </el-form-item>
                <el-form-item label="性别">
                  <el-radio-group v-model="form.gender" style="width: 178px">
                    <el-radio :label="1">男</el-radio>
                    <el-radio :label="2">女</el-radio>
                  </el-radio-group>
                </el-form-item>
                <el-form-item label="城市" prop="city" size="mini">
                  // 省市区级联选择器
                  <el-cascader
                    v-model="selectedOptions"
                    size="mini"
                    :options="options"
                    filterable
                    clearable
                    style="width: 250px"
                    @change="handleChange"
                  />
                </el-form-item>
                <el-form-item label="">
                  <el-button
                    :loading="saveLoading"
                    size="mini"
                    type="primary"
                    @click="doSubmit"
                  >更新信息</el-button>
                </el-form-item>
              </el-form>
            </el-tab-pane>
          </el-tabs>
        </el-card>
      </el-col>
    </el-row>
  </div>
</template>

<script>
import { mapGetters } from 'vuex'
import store from '@/store'
import { saveUser } from '@/api/user'
// 导入省市区数据组件
import { regionData, CodeToText, TextToCode } from 'element-china-area-data'
export default {
  name: 'Center',
  data() {
    return {
	  // 存放用户信息
      form: {},
      // 将省市区数据赋给级联选择器
      options: regionData,
      // 存放用户选择后省市区的信息
      selectedOptions: [],

    }
  },
  computed: {
    ...mapGetters([
      'user',
      'baseApi'
    ])
  },
  created() {
    store.dispatch('getInfo').then(() => {
      this.form = { id: this.user.id, nickName: this.user.nickName, gender: this.user.gender, phone: this.user.phone,
        province: this.user.province, city: this.user.city, country: this.user.country }
      if (this.form.country !== '') {
        this.selectedOptions = [TextToCode[this.form.province].code, TextToCode[this.form.province][this.form.city].code, TextToCode[this.form.province][this.form.city][this.form.country].code]
      } else {
        this.selectedOptions = [TextToCode[this.form.province].code, TextToCode[this.form.province][this.form.city].code]
      }
    })
  },
  methods: {
    // 省市区级联选择器选择后更新用户前端
    handleChange(value) {
      this.form.province = ''
      this.form.city = ''
      this.form.country = ''
      for (let i = 0; i < this.selectedOptions.length; i++) {
        if (i === 0) { this.form.province = CodeToText[this.selectedOptions[i]] }
        if (i === 1) { this.form.city = CodeToText[this.selectedOptions[i]] }
        if (i === 2) { this.form.country = CodeToText[this.selectedOptions[i]] }
      }
    },
    // 提交用户更新信息
    doSubmit() {
      if (this.$refs['form']) {
        this.$refs['form'].validate((valid) => {
          if (valid) {
            this.saveLoading = true
            saveUser(this.form).then(() => {
              this.$notify({
                title: '更新成功',
                type: 'success',
                duration: 2500
              })
              store.dispatch('getInfo').then(() => { })
              this.saveLoading = false
            }).catch(() => {
              this.saveLoading = false
            })
          }
        })
      }
    }
  }
}
</script>

五、 实现效果

六、 前端源码

https://gitee.com/zhuhuix/startup-frontend
https://github.com/zhuhuix/startup-frontend

相关文章