Open zhouzhili opened 5 years ago
今天在重构之前写的代码的时候,发现一个接口请求数据有问题,传递给后端的是一个数组,但是在控制台里面却变了样,参数名称后面诡异的加了一个'[]',回忆了一下自身并没有对这个参数进行了格式化操作,Google 一番发现这是 axios 的锅
经过实验,axios 的 get 方法中使用 params 时对于 js 数组类型的参数的默认操作比较诡异,会使得参数名后带上'[]'字符串,原因是 axios 对 params 格式化采用的是qs这个库,因此可以使用 qs 自带的 arrayFormat 参数配置解决这个问题,大致配置如下:
const qs = require('qs') axios.get(url, { params: { arr: [1, 2, 3] }, paramsSerializer: function(params) { return Qs.stringify(params, { arrayFormat: 'repeat' }) } })
后端接收为 url-query 数组,即'id=1&id=2&id=3'
如果是在组件中需要挂载全局变量的话,没法直接使用 this.prototype,组件实例没有这个属性,只有proto,但是这个属性是被废弃的,不建议使用。在组件中使用 this.\$options._base 即为 Vue 构造函数,在构造函数原型上挂载属性即可挂载到 Vue 全局中,在所有组件中使用。 参考:Vue 技术揭秘:构造子类构造函数
项目中的组件常分为基础组件和业务组件,基础组件为对一些页面基本构成部分的封装,如 element-ui 等属于这一类,业务组件则为适应业务要求而对基础组件进行的再封装,一般基础组件的适应性更强。
在组件封装中不要过度封装,组件应该着重于展示部分,接收数据,根据数据展现出应有的形态,应本着高内聚,低耦合原则。prop 尽量只传递一些基本数据类型,并做数据验证。不要将非展示的逻辑强行封装到组件中,导致组件适应性差,不应把父组件应处理的逻辑放到组件中处理,组件只接受数据,返回渲染结果
业务组件可以适当的将业务逻辑封装进组件内部,有时候业务性质高度统一,但是又是不同的页面只是数据接口改变而已,这样可以将整个页面进行封装,实现复用。
如上图所示,在产品中已对 QueryForm 和 table 进行了一次封装,但是现在有 2 个类似的页面,都有对表格数据的增删改查需求,表格操作按钮的弹窗和逻辑都高度相似,UI 部分和业务逻辑部分都基本不变,只是接口名改变了。简单的方式就是新建一个文件,代码复制一遍。如果封装的话,需要把各自的增删改查接口通过 prop 传进组件里面才能实现最大的复用。因此我选择了后者,如果后面再出一个类似的页面就可以直接使用了。但是问题是需要增删改查接口传递的参数一致才行,不然需要针对每个接口做数据格式化,写一堆 if else 语句来进行判断,因此业务组件的耦合性相当高,扩展性不强。如果把页面所需要处理的事件都冒泡到父组件来处理的话,那也就失去了组件化的意义。如何对组件进行封装以及封装到哪种地步都需要根据情况来考虑。
我封装的组件使用方式如下所示:
<template> <div> <div v-if="showIndex" class="flex-1-box"> <service-list service-type="mysql" :get-table-list-api="getMysqlList" :init-api="init" :update-api="update" :rest-api="resetPsw" /> </div> <router-view v-else></router-view> </div> </template>
1.Axios 在 GET 请求中传递数组问题
今天在重构之前写的代码的时候,发现一个接口请求数据有问题,传递给后端的是一个数组,但是在控制台里面却变了样,参数名称后面诡异的加了一个'[]',回忆了一下自身并没有对这个参数进行了格式化操作,Google 一番发现这是 axios 的锅
经过实验,axios 的 get 方法中使用 params 时对于 js 数组类型的参数的默认操作比较诡异,会使得参数名后带上'[]'字符串,原因是 axios 对 params 格式化采用的是qs这个库,因此可以使用 qs 自带的 arrayFormat 参数配置解决这个问题,大致配置如下:
后端接收为 url-query 数组,即'id=1&id=2&id=3'
2. vue 组件没有 prototype
如果是在组件中需要挂载全局变量的话,没法直接使用 this.prototype,组件实例没有这个属性,只有proto,但是这个属性是被废弃的,不建议使用。在组件中使用 this.\$options._base 即为 Vue 构造函数,在构造函数原型上挂载属性即可挂载到 Vue 全局中,在所有组件中使用。 参考:Vue 技术揭秘:构造子类构造函数
3.在项目中组件的封装
项目中的组件常分为基础组件和业务组件,基础组件为对一些页面基本构成部分的封装,如 element-ui 等属于这一类,业务组件则为适应业务要求而对基础组件进行的再封装,一般基础组件的适应性更强。
在组件封装中不要过度封装,组件应该着重于展示部分,接收数据,根据数据展现出应有的形态,应本着高内聚,低耦合原则。prop 尽量只传递一些基本数据类型,并做数据验证。不要将非展示的逻辑强行封装到组件中,导致组件适应性差,不应把父组件应处理的逻辑放到组件中处理,组件只接受数据,返回渲染结果
业务组件可以适当的将业务逻辑封装进组件内部,有时候业务性质高度统一,但是又是不同的页面只是数据接口改变而已,这样可以将整个页面进行封装,实现复用。
如上图所示,在产品中已对 QueryForm 和 table 进行了一次封装,但是现在有 2 个类似的页面,都有对表格数据的增删改查需求,表格操作按钮的弹窗和逻辑都高度相似,UI 部分和业务逻辑部分都基本不变,只是接口名改变了。简单的方式就是新建一个文件,代码复制一遍。如果封装的话,需要把各自的增删改查接口通过 prop 传进组件里面才能实现最大的复用。因此我选择了后者,如果后面再出一个类似的页面就可以直接使用了。但是问题是需要增删改查接口传递的参数一致才行,不然需要针对每个接口做数据格式化,写一堆 if else 语句来进行判断,因此业务组件的耦合性相当高,扩展性不强。如果把页面所需要处理的事件都冒泡到父组件来处理的话,那也就失去了组件化的意义。如何对组件进行封装以及封装到哪种地步都需要根据情况来考虑。
我封装的组件使用方式如下所示: