博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
利用element-ui封装地址输入的组件
阅读量:4364 次
发布时间:2019-06-07

本文共 3957 字,大约阅读时间需要 13 分钟。

  我们前端做项目时,难免会遇到地址输入,多数情况下,我们都是提供一个省市三级联动,加上具体地址输入的Input输入框给用户,用以获取用户需要输入的真实地址。在需要对用户输入的数据进行校验的时候,我们会单独针对省市的三级联动和具体地址栏单独校验。也基本上能够完成项目需求。

  然而当我们转向vue+element做项目时,会产生一个比较尴尬的问题。在element组件库当中,对需要校验的字段是通过在el-form-item这一组件标签名上添加prop属性来校验的,如果依然按照以前的方法对省市联动和地址栏分别校验的话,就得把省市选择和地址输入分成两个el-form-item组件内蓉来写,我们可以看一下,实际形成的布局。

  

  这就比较难受了,用户本来也就是需要输入个地址,我们提供给用户级联选择器的目的是方便用户进行省市区的选择,然而现在的情况确是,用户必须进行二次验证。

  转换思路,用户也可以把两栏并成一栏,展示会比较好看一点。

    

  这么来看布局似乎没问题了,但是另一个问题又产生了,element本省提供的校验方案是通过el-form-item的属性prop对用户传入的参数进行校验。

  也就是说prop必须是字符串,那么这时候,就没办法对两个字段同时校验了,唯一的方案似乎就变成了:把这两个字段变成一个对象,通过自定义校验方法来校验该对象内的数据的值。类似于:

address:{    district:[],    address:''}

  在el-form-item上写上prop='address',然后自定义校验方法,通过validator进行校验。

  想法已经完成了,那么如果项目当中不仅仅一处用到地址输入的话,我们是不是就有必要对该组件进行封装,让他成为我们的常备组件之一了。

  好吧!那就开始封装组件了。

  我们的组件封装的仅仅是级联选择器和Input输入框,并不包含校验规则,毕竟是还有其他需要校验的组件。

  组件的内容可能就很简单了。

  一个.vue文件, template:

  script:

  

import { regionData, CodeToText, TextToCode } from 'element-china-area-data'export default {  name: 'VAddress',  props: {    value: {      type: Object,      default () {        return {          address: '',          areaCity: '',          areaCode: '',          areaDistrict: '',          areaProvince: ''        }      }    }  },  model: {    prop: 'value',    event: 'change'  },  data () {    return {      dis: [],      regionData,      mapLabel: TextToCode,      mapCode: CodeToText,      ...this.value    }  },  methods: {    handleChange (e) {      let val = {        ...this.value,        address: this.address      }      this.$emit('update:value', val)      this.$emit('change', val)    },    handleAddressChange (values) {      console.log(values)      const b = ['areaProvince', 'areaCity', 'areaDistrict']      if (values.length > 0) {        let initialValue = {          ...this.value,          'areaProvince': '',          'areaCity': '',          'areaDistrict': '',          'areaCode': values[values.length - 1]        }        const val = values.reduce((acc, curret, index) => {          let value = this.mapCode[curret]                  return {            ...acc,            [b[index]]: value          }        }, initialValue)        this.$emit('change', val)        // sync更新        // this.$emit('update:value', val)      }    },    getCurrentRegion (val) {      let address = val      if (!Array.isArray(val) && typeof val === 'object') {        let { areaProvince, areaCity = '', areaCode } = val        address = [this.mapLabel[areaProvince], this.mapLabel[areaCity], areaCode]        if (address.some(item => item === undefined)) address = []      }      return address    },    initDis (val) {      this.dis = this.dis.length === 0 ? this.getCurrentRegion(val) : this.dis    }  },  created () {    if (this.regionData.length > 0 && this.value.areaCode) {      this.initDis(this.value)    }  },  watch: {    value: {      handler (val) {        this.address = val.address        if (this.regionData.length > 0) {          this.initDis(val)        }        if (Object.values(val).every(item => !item)) this.dis = []      },      deep: true    }  }}

  需要注意的一个是:

model: {    prop: 'value',    event: 'change'}

  具体解释请转到,我只简单说一句,就是提供给组件使用时绑定v-model,因为v-model默认传递的是value属性,处理的是input事件,而通过在子组件定义model属性,我们就可以修改v-model处理的事件和传递的属性。因为很正常,我们这里有两个form表单控件的内容,肯定没办法依赖v-model的input事件进行处理。如果实在不喜欢这种写法,也可以在组件使用时,避开v-model的用法,转而通过:value.sync进行属性传递,在事件处理是通过this.$emit('update:value', val)来进行类似处理,这也就是看起来没有v-model那么牛X一样,其实结果是一致的。

  我们在组件内分别对级联选择器和Input输入框做change事件处理,从而获取到最新的数据,转换成使用该组件的父组件内,关于级联选择器的change事件,依赖于各个公司后台开发人员需要前端传回什么样的数据,进行处理。

  我们的项目当中,后台需要省市区的数据格式为areaProvince, areaCity, areaDistrict, areaCode,所以在级联选择器change的时候,我需要及时的将其获取到的数组(省市区的code值),转换成对应的具体的省份、城市、区,加上区的areaCode,然后传递给后台,具体的得依赖项目需求各自处理。

  这是vue+element的地址输入的组件封装,后面还会有一个react+antd关于地址输入的组件封装,相较于element,antd提供了自定义form表单控件的功能,所以封装起来也就更容易一点,也更容易理解。

  

 

  

转载于:https://www.cnblogs.com/zhuhuoxingguang/p/10971667.html

你可能感兴趣的文章
SDK 操作 list-view control 实例 -- 遍历进程
查看>>
由于SSH配置文件的不匹配,导致的Permission denied (publickey)及其解决方法
查看>>
65. Valid Number
查看>>
检查MySQL主从数据一致性
查看>>
结构化日志:出错时你最想要的好朋友
查看>>
Git常用命令总结
查看>>
[算法练习]Excel Sheet Column Title
查看>>
【原创】MapReduce编程系列之表连接
查看>>
IOS开发之Swift学习笔记
查看>>
【Java基础】用LinkedList实现一个简单栈的功能
查看>>
线段树C-A Simple Problem with Integers(树懒线段树)
查看>>
Ferguson游戏
查看>>
PHPExcel
查看>>
create your own github repository and build link to your local project
查看>>
Leetcode-Convert Sorted Array to BST
查看>>
form表单,submit,ajax提交
查看>>
三大平衡树(Treap + Splay + SBT)总结+模板
查看>>
关于数据库名、实例名
查看>>
多线程不安全的函数列表
查看>>
Codeforces Round #318 (Div. 2) B Bear and Three Musketeers (暴力)
查看>>