vue + mint-ui 的 picker 省市区三级联动,以及编辑回显,可直接复制封为组件

最近用vue做一个公众号用到了mint-ui的picker,选择地区的三级联动,由于picker无法加载动态数据,经过各种百度,最后使用promise对象,将异步转换为同步。完美解决三级联动效果,文章借助于:https://blog.csdn.net/NAMECZ/article/details/85286095

<template>
    <div>
        <mt-popup v-model="areaVisible" position="bottom">
            <mt-picker :slots="slots" valueKey="name" showToolbar @change="selectArea">
                <div class="mui-card-footer">
                    <a v-on:click="cancel" class="mui-card-link">取消</a>
                    <a v-on:click="determine" class="mui-card-link">确认</a>
                </div>
            </mt-picker>
        </mt-popup>
    </div>
</template>

<script>

export default {
  data () {
    return {
      flag: false, // 初始时禁止picker自动加载
      areaVisible: false, // 初始选择地区弹窗为关闭状态
      cityName: '', // 最终选中的地区的名字
      cityCode: '', // 最终选中的地区的id
      slots: [ // 渲染格式必须留着
        { // 省
          flex: 1,
          values: ['请选择'], // 省份数组
          className: 'slot1',
          textAlign: 'center',
          value: 14
        },
        { // 分隔符
          divider: true,
          content: '-',
          className: 'slot2'
        },
        { // 市
          flex: 1,
          values: ['请选择'],
          className: 'slot3',
          textAlign: 'center'
        },
        {
          divider: true,
          content: '-',
          className: 'slot4'
        },
        { // 县
          flex: 1,
          values: ['请选择'],
          className: 'slot5',
          textAlign: 'center'
        }
      ]
    }
  },
  watch: { // 监听值变动
    // 监听隐藏显示值变动
    areaVisible (data) {
      this.$emit('cancel', this.areaVisible) // 监听组件是否隐藏把值传给父组件
    }
  },
  props: ['initial', 'onpid', 'oncityCode'], // initial picker显示隐藏状态,onpid 详情数据id(有则编辑),oncityCode 详情返回的省市区id
  methods: {
    // 选择地区
    selectArea (picker, values) {
      if (this.flag) { // 组件初始化默认禁止picker自动加载
        this.area(values[0].id).then((data) => { // 通过一级 省的id 获取市的列表
          picker.setSlotValues(1, data) // 将市的地区列表放入 slots的二级列表中
        })
        this.area(values[1].id).then((data) => { // 通过 二级 市的id  获取区域的列表
          picker.setSlotValues(2, data) // 将区的地区列表放入 slots的三级列表中
        })
        var arr = picker.getValues()
        // console.log(arr)
        this.cityName = `${arr[0].name}-${arr[1].name}-${arr[2].name}`
        this.cityCode = {
          province: arr[0].id,
          city: arr[1].id,
          county: arr[2].id
        }
      }
    },
    // 调取地区列表的函数
    area (id) {
      // 所以我们这里使用promise对象,将异步转换为同步。
      return new Promise((resolve, reject) => {
        this.$http.get('receive/address/area/' + id).then((json) => {
          if (json.body.code === 200) {
            resolve(json.body.data)
          }
        })
      })
    },
    // 点击确定
    determine (e) {
      this.areaVisible = !this.areaVisible // 关闭
      this.$emit('determine', [this.cityName, this.cityCode]) // 把选中的名字以及id传给父组件
    },
    // 点击取消
    cancel () {
      this.areaVisible = !this.areaVisible
      this.$emit('cancel', this.areaVisible) // 给父方法传值
    },
    popup () { // 父方法传值
      this.areaVisible = !this.initial
      this.flag = true
    }
  },
  beforeMount () { // 默认取省级数据,不能再methods请求否则无法渲染
    // 页面初始化默认取省级数据 0 默认id
    this.$http.get('receive/address/area/0').then((json) => {
      if (json.body.code === 200) {
        this.slots[0].values = json.body.data // .map(data => data.id)

        // 编辑回显 如有地址id为编辑
        if (parseInt(this.onpid)) {
          var index = json.body.data.findIndex(fruit => fruit.id === this.oncityCode.province) // 得到指定省id数据下标
          this.slots[0].defaultIndex = index // 设置初始值下标

          // 根据省拿到市数据 并设置初始值
          this.area(this.oncityCode.province).then((data) => { // 通过一级 省的id 获取市的列表
            var index = data.findIndex(fruit => fruit.id === this.oncityCode.city) // 得到指定市id数据下标
            this.slots[2].values = data // 市数据
            this.slots[2].defaultIndex = index // 设置初始值下标
          })

          // 根据省市到区数据 并设置初始值
          this.area(this.oncityCode.city).then((data) => { // 通过二级 市的id 获取区的列表
            var index = data.findIndex(fruit => fruit.id === this.oncityCode.county) // 得到指定区id数据下标
            this.slots[4].values = data // 区数据
            this.slots[4].defaultIndex = index // 设置初始值下标
          })
        }
      } else {
        this.$toast(json.body.message)
      }
    })
  }
}
</script>

<style lang="scss" scoped>
.mui-card-footer{border-bottom: 1px solid #eee;}
.mint-popup-bottom{width: 100%;}
</style>

猜你喜欢

转载自blog.csdn.net/u014206461/article/details/105863073