vue点击添加一行输入框_还是自己Vue.js封装地区级联组件吧!

本文详细介绍了如何使用Vue.js封装一个地区级联组件,包括组件封装的初衷、准备工作、代码实现过程,以及组件的优化和API文档的编写。通过这个教程,读者可以了解如何创建自定义的Vue组件并实现数据的双向绑定。
摘要由CSDN通过智能技术生成

dea29c9c78af8acec777357601c9f92a.png

Vue.js封装地区级联组件

一、怎么就想不开要自己封装?

当我们遇到复杂的需求或者比较不好实现的交互时,我们第一时间一定是会想到使用组件,并且现在有很多优秀的组件库供我们使用,但是在公司的项目里,所有的主题色都是深色系,因为我们是给GA做的项目,想要把这些组件修改成统一的风格,那就要大费周章了(其实就是想要自己的组件库),那干脆我们动手自己实现吧!

二、准备工作

  • 我们要有一个演示页面,或者在已有的 vue 项目中能够展示,因为我们是要建立组件库,所以我们直接新建 vue-cli 项目。
  • 准备地区级联的数据,我是从 github 上下载的到区级的数据。
  • 准备好一杯咖啡,开搞!

地区数据连接:https://github.com/modood/Administrative-divisions-of-China

三、开始敲代码

  1. 编写组件大体结构

新建组件文件,命名为 if-cascader,这里使用的 sass 编辑样式。

4549b830bfdab35f06b4fd91024fcbc4.png

新建好组件后我们还需要将它引入到我们的展示页面,测试一下有没有成功引入:

d81acd6af82989ed07e85e68c825d1cb.png

接下来我们要冷静下来思考,地区数据是需要用户填写还是将数据封装在组件内?答案当然是让用户自己填写,因为如果将地区数据封装在组件内将会导致几个问题:

  • 地区数据更新后,需要组件维护新的数据,并且用户也需要更新组件。
  • 封装在组件里会导致组件的体积变大,无法快速加载组件。

所以最好的办法就是在用户使用组件时,在本地服务器请求数据后填充到组件内,但这就需要有一个统一的格式,我们以上面链接中下载的数据格式为准进行数据处理。

2. 开始写样式和逻辑

处理好数据后写出基本的样式:

623e4365d4de5970be0b5af66b34b3a6.png
注意:图中 :value 改成 v-model 才能实现动态数据。
截图时还未修改,如果使用 :value 需要添加 computed 周期 return 绑定的 inputVal。

<input type="text" readonly :value="inputVal" @change="changeSelect()">
       
···
       
computed: {
    changeSelect() {
        return this.inputVal;
    }
}
  • 这里readonly是因为输入框中的数据是需要选择得出的,并不需要用户手动输入;
  • 动态绑定变量用来保存用户所选择数据;
  • 第二个close图标用于点击可以清空输入框数据;
  • 这里我把演示文件的边框去掉了,在组件里加上了我们UI要求的组件样式。

现在是我们需要数据的时候了,将用户传入的地区数据通过props传值传入并进行遍历渲染!

00be698c85752ef94d14806abcef2006.png

编辑好UI给的样式,并将一级的地区名称渲染出来,并建立好下面级联的样式,这里用的定位来写下拉容器的位置。
需要注意的是:key绑定的是地区的code,而不是v-for产生的index,一级目录不会发生变化所以看不出问题,当二三四级下拉根据上一级变化时,就会发现数据不动态变化的问题,这里参考文档。

3. 增加交互

现在我们需要添加点击事件来实现点击输入框出现下拉,点击一级目录出现二级目录:

afdb653d4384c9e42a54e513e0917e2f.png

到这里就基本实现了原理,下面将三四级都一起实现!

3732cfe7e83379b84a95a0cb75fb0a54.png

因为数据一层套一层,这里以第三级为例,要考虑用户第一次选择和选择完四级后重新选择,所以要做一次判断和数据的重新处理。
现在基本的点击交互已经实现了,最后完善一下就可以了,就是用户选择完之后点击其他地方关闭下拉,给组件添加 ref 并在 mounted 周期添加方法即可,当然也可以在用户选择完第四级后自动关闭,这里是需求就不多说啦。

b4121fe51ef0101e09c1cd6855926e7c.png

4. 双向绑定

用户使用组件的时候肯定是需要拿到数据的,接下来最重要的一步就是使数据能够双向绑定,按照文档添加model就可以了,再在需要的时候调用$emit把处理好的数据传给他们!最好的调用时机就是在数据变化时就给用户(父组件)传值,所以添加 watch !

1ceeb7043e590f22908dc897f0ce7afb.png
  • change事件返回数据格式:[ { "name": "吉林省", "code": "220000" }, { "name": "四平市", "code": "220300" }, { "name": "梨树县", "code": "220322" }, { "name": "梨树镇", "code": "220322100" } ];
  • 添加change事件返回一个原始的选择数据可以让用户自由的处理他想要的数据样式和结构;

接下来就是数据的回显,只需要在加载组件时将用户给的数据(如:吉林省/四平市/梨树县/梨树镇)分解,后遍历拿到code和index进行变量赋值就可以了,但这需要规定好间隔符!

5. 优化组件

既然做的是组件,当然还需要一些可自定义的东西~所以这里再加几项可以让用户自由发挥的配置!其实在上面的截图中已经有体现了,我自己分别添加了四个自定义选项。

1).placeholder

用于展示提示信息,增加props传值,给组件中的input添加动态绑定。

<input type="text" readonly v-model="inputVal" @click="showSelectFn($event)" :placeholder="placeholder ? placeholder :'请选择'">

2).level

用于用户自定义显示几级级联菜单,增加props传值,并给每一级容器添加判断。

html:

<div class="if-cascader-level if-cascader-level-one if-cascader-level-district" 
     v-show="showSele && selectLevel >= 1">
···
</div>
<div class="if-cascader-level if-cascader-level-two if-cascader-level-district"
      v-if="selectedValue.length >= 1 && showSele && selectLevel >= 2">
···
</div>   
<div class="if-cascader-level if-cascader-level-three if-cascader-level-district"
     v-if="selectedValue.length >= 2 && showSele && selectLevel >= 3">
···
</div>   
<div class="if-cascader-level if-cascader-level-four if-cascader-level-district"
     v-if="selectedValue.length >= 3 && showSele && district[firstIndex].children[secondIndex].children[thirdIndex].children && selectLevel >= 4">
···
</div> 

js中添加一个默认值:3

data() {
        return {
            selectLevel: this.level || 3,
            ···
        };
    },

3).spacer

用于用户自定义间隔符,增加props传值,并且替换处理数据时的"/"为变量。

data() {
    return {
        spacerStr: this.spacer || '/',
        ···
    };
},
methods:{
	···
    selectThree(){
    	···
    	this.inputVal = this.selectedValue.join(this.spacerStr);
    },
    ···
}

4).options/distrist

用于用户自定义数据,增加props传值,并且添加整体的判断修改:

  • district有值时是使用地区级联,也就是上面写好的逻辑,options有值时使用另一套判断,规定用户使用[label:"",value:"",children:[]]的数据结构;
  • 遍历时的key就不能是地区的code了,但也不能使用v-for的index,应该使用value作为key。

还有很多兼容的问题需要使用中慢慢修改,因为我也是第一次研究并且应用场景不够多,所以……我觉得还是有很多bug的(嘘),我在这里直接使用了另一套结构,但逻辑基本没变,需要修改的就只有上面提到的一些变量名。

39e8368dee64e34e748ec3319852c7c6.png

6. API文档

最后根据配置写好一个文档供用户,也就是我们以后使用时查看。截图直接使用的公司在用的API所以是gdv-前缀,组件到这里就完结撒花!✿✿ヽ(°▽°)ノ✿

第一次写文章有一点乱,希望各位大佬们多多包涵,不足的地方尽管提出来,我要跟随大佬们一起前进!

89189e5d34e4287244cc0779cc66605e.png
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值