ant-design-vue 快速避坑指南(推荐)

ant-design-vue是蚂蚁金服 Ant Design 官方唯一推荐的Vue版UI组件库,它其实是Ant Design的Vue实现,组件的风格与Ant Design保持同步,组件的html结构和css样式也保持一致。 用下来发现它的确称得上为数不多的完整的VUE组件库与开发方案集成项目。

本文主要目的是总结一些开发过程中比较耗时间去查找,文档中没有具体说明的常见问题,同时希望能给新上手此框架的同学提供一些参考作用。

1.Table对接后台返回数据

针对Table数据格式与后他接口返回数据格式不一致问题,修改 `@/components/table/index.js` 132行起

主要修改pageNo,pageSize,totalCount,data这字段与后台返回字段一致就OK了

result.then(r => {
 this.localPagination = Object.assign({}, this.localPagination, {
  current: r.pageNo, // 这里修改当前分页字段
  total: r.totalCount, // 这里修改总记录数字段
  showSizeChanger: this.showSizeChanger,
  pageSize: (pagination && pagination.pageSize) ||
   this.localPagination.pageSize // 这里修改总记录数当前页数字段
 })
  //r.data中的data修改为返回列表字段
 if (r.data.length == 0 && this.localPagination.current != 1) {
  this.localPagination.current--
  this.loadData()
  return
 }
 !r.totalCount && ['auto', false].includes(this.showPagination) && (this.localPagination = false)
 this.localDataSource = r.data // 返回结果中的数组数据
 this.localLoading = false
});

2.table操作栏参数问题

在table的dataSource中指定的每一个数据中,都必须包含有name为key的对象,而显示出的数据就是相应key对应的数据,dataIndex就用来声明列数据在数据项中对应的key

然而在操作列中,我们一般需要传入不知一项数据,试了一下如下图配置dataIndex,数据并不能正确传入slot-scope中

columns: [
  ...
  {
      title: '操作',
      dataIndex: 'id,text',
      key: 'id',
      scopedSlots: { customRender: 'operation' }
  }

多尝试后发现,其实只要不配置dataIndex就好了。。。slot-scope自定义一个字段,自然就拿到了整行数据

3.table分页组件展示条数

:pagination="{showTotal: total => `共${total}条`}"

4.神奇的最后一个标签隐藏问题

使用可编辑tags过程中值得注意的问题,一般删除某个tag不止是从DOM中删除这个tag,而是需要调接口修改数据,那么这时候如果选择用修改完的数据动态渲染tag列表,并且理所当然地认为动态绑定数据就不需要关心数据手动处理,问题就出现了:

假如一共有5个tag,现在删除第一个tag,并调用接口返回新数据,注意tags默认的删除操作也不是从DOM中删除这个tag,而是将这个tag设置为```display:none```!这就导致了一个很神奇的问题,此时新返回的tags数组长度已经 -1,而它仍然认为当前列表的第一个Tag是隐藏的,最后呈现的效果就是只剩3个Tag,此时再接着删除第一个tag(其实是第二个),那么就只剩1个tag了。。

<a-tag
 v-for="(tag, index) in Tags"
  :key="tag.id"
  :closable="tagCloseable"
  :afterClose="() => handleTagStatus(0,tag)"
  >{{ tag.name }}
</a-tag>

这个问题貌似没什么好的办法,只能放弃绑定动态数据,判断接口调用成功后,再用文档中的手动操作增减数据的办法:

this.Tags = this.Tags.filter(tag => tag.id !== removeTag.id)

5.表单的各种常规操作

单独触发某个字段的校验:

this.form.validateFields(['name'], { force: true }) 

清除某个字段的值:

this.form.resetFields(`name`,'')

设置表单初始值:

this.form.resetFields(`name`,'')

注意:不初始化的值用undefined而非‘',否则下拉框会不显示placeholder!

自定义文件上传的action函数:

<a-upload :customRequest="upLoad"></a-upload>

upLoad (info) {
  let file = info.file;
  let param = new FormData(); //创建form对象
  param.append('file',file);//通过append向form对象添加数据
  console.log(param.get('file')); //FormData私有类对象访问不到,可以通过get判断值是否传进去
  let config = {
    headers:{'Content-Type':'multipart/form-data'}
  };
  this.$http.post(url, param, config).then(res => {
    ...
  })
},

6.接口跨域携带cookie问题

做单点登录时需要在请求头中携带cookie,遇到了很坑人的问题,实际原因是对mock.js的实现不够了解。

还是在`@/src/utils/request.js`,这里创建了axios实例供全局调用,根据axios文档,**在创建** axios 实例时添加:`withCredentials: true`

const service = axios.create({
  baseURL: `${process.env.VUE_APP_BASEURL}/backend`,
  withCredentials: true,
 timeout: 6000
})

结果发现接口请求仍然不带cookie,无奈试了一下用fetch请求`fetch(url, { credentials: 'include', mode: 'cors' })`,发现可以携带cookie,百思不得其解,两者都是基于promise实现的,但是fetch在写法和拦截请求响应等方面都比较麻烦,全部替换成fetch也不太现实。最后才发现,是mock.js没有注释(`main.js`中注释掉就好了),原来mock.js是通过拦截XHR请求来实现的接口模拟,Axios本质上也是对原生XHR的封装,只不过它是Promise的实现版本,所以它当然被拦截了,而fetch脱离了XHR,这也是fetch请求能正常携带cookie的原因,这里还没有全部梳理清楚,打算在后一篇中详细介绍一下

7.单点登录的实现

全局的路由钩子在`permission.js`中,一般单点登录、权限验证都是在这里处理,这里也不例外。没什么特别的,需要注意的一点就是,不要忘记对页面其他接口的统一无权限处理,和403请求的响应处理。同时画个流程图会更快一些,这里就记录一下吧:

流程图:

路由钩子

路由钩子的处理:

router.beforeEach((to, from, next) => {
 // 对403无权限的处理
 if (to.path === '/403') {
  next()
 } else {
  if (roles) {//已登陆
   next()
  } else {
      //获取用户信息,GetUserInfo逻辑如下:
      //status=403 && reject(res),返回包含status;
      //status=1005 && reject(res.data)返回重定向的URL;
      //status=1000 && resolve()
   store
    .dispatch('GetUserInfo')
    .then(res => {
     next()
    })
    .catch((e) => {
     if (e.status) {
      next({ path: '/403' })
     } else {
            //拼接URL跳去登陆页,登陆成功会重定向回当前页(login_redirect)
      const url = e.substring(0, e.lastIndexOf('redirect')) + 'redirect=' + login_redirect
      window.location.href = url
     }
    })
  }
 }
})

`@/ src/utils/request.js`中接口返回的统一处理:

service.interceptors.response.use((response) => {
  if (response.data.status === 1005){
      //... 同上跳去登陆页
  }else{
    //为返回数据做统一处理
    return response.data
  }
}, err) 

7.引入eCharts

1)npm install

2) components下新建barChart.vue ,import echarts from 'echarts',正常操作...

3) resize触发图表自适应

echart有resizeAPI,一般是在图表组件如barChart.vue里面手动监听窗口resize

mounted() {
  window.addEventListener("resize", () => {
    this.chart.resize();
  });
},

后面借鉴element-admin, 利用mixins实现了更完善的统一处理方法:

1)定义一个mixin:resize.js

import { debounce } from '@/utils'//防抖函数
export default {
 data() {
  return {
   $_sidebarElm: null
  }
 },
 mounted() {
  this.__resizeHandler = debounce(() => {
   if (this.chart) {
    this.chart.resize()
   }
  }, 100)
  window.addEventListener('resize', this.__resizeHandler)

  this.$_sidebarElm = document.getElementsByClassName('sidebar-container')[0]
  this.$_sidebarElm && this.$_sidebarElm.addEventListener('transitionend', this.$_sidebarResizeHandler)
 },
 beforeDestroy() {
  window.removeEventListener('resize', this.__resizeHandler)

  this.$_sidebarElm && this.$_sidebarElm.removeEventListener('transitionend', this.$_sidebarResizeHandler)
 },
 methods: {
  $_sidebarResizeHandler(e) {
   if (e.propertyName === 'width') {
    this.__resizeHandler()
   }
  }
 }
}

2)@/components/_utils/util.js中添加防抖函数

export const debounce = (func, wait, immediate) => {
 let timeout, args, context, timestamp, result
 const later = function() {
  // 据上一次触发时间间隔
  const last = +new Date() - timestamp
  // 上次被包装函数被调用时间间隔 last 小于设定时间间隔 wait
  if (last < wait && last > 0) {
   timeout = setTimeout(later, wait - last)
  } else {
   timeout = null
   // 如果设定为immediate===true,因为开始边界已经调用过了此处无需调用
   if (!immediate) {
    result = func.apply(context, args)
    if (!timeout) context = args = null
   }
  }
 }
 return function(...args) {
  context = this
  timestamp = +new Date()
  const callNow = immediate && !timeout
  // 如果延时不存在,重新设定延时
  if (!timeout) timeout = setTimeout(later, wait)
  if (callNow) {
   result = func.apply(context, args)
   context = args = null
  }
  return result
 }
}

3)resize监听方法混入图表组件即可

mixins: [resize]

总结

以上所述是小编给大家介绍的ant-design-vue 快速避坑指南,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对我们网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!

(0)

相关推荐

  • Vue中Table组件行内右键菜单实现方法(基于 vue + AntDesign)

    最近做的一个项目是基于 vue + AntDesign 的.由于项目要求,需要在 Table 组件的行内点右键的时候弹出菜单.在线演示地址及最终效果图如下: 在线演示地址>> 首先新建一个Table组件的实例: <a-table :columns="columns" :rowKey="record => { return record.INDEX;}" :dataSource="tableData" /> ... c

  • ant-design-vue 实现表格内部字段验证功能

    表格内 column 可输入的需求还是很常见的,尤其有一些业务场景就是表单内部有一个表格,然后表格的某些列是个进行输入的,就像下面这样 下单数量 内容不能为空 下单数量 必须输入正整数 翻阅 ant-design-vue 官网并没有发现说表单内表格字段验证的方案,但是有一个 自行处理表单数据 的介绍 那我们是不是可以参考这个方案去实现咱自己的业务需求呢,下面就开始说一下实现方案 <a-table :columns="columns" bordered :rowKey="

  • Ant Design Vue 添加区分中英文的长度校验功能

    原本的maxLength属性是不区分全角/半角字符的,对于一些可中英文混合输入地方而言不太合适.所以想找一个可区分全角/半角字符的校验,而且要保证一定的可重用性. 百度搜了一圈都没找到合适的现成的解决方案,所以自己试着基于v-decorator的自定义校验validator实现了一下,核心代码如下: 校验插件 const validators = { /** * 可区分全角字符/半角字符的长度校验. * @param min * @param max * @returns {Function}

  • ant-design-vue 快速避坑指南(推荐)

    ant-design-vue是蚂蚁金服 Ant Design 官方唯一推荐的Vue版UI组件库,它其实是Ant Design的Vue实现,组件的风格与Ant Design保持同步,组件的html结构和css样式也保持一致. 用下来发现它的确称得上为数不多的完整的VUE组件库与开发方案集成项目. 本文主要目的是总结一些开发过程中比较耗时间去查找,文档中没有具体说明的常见问题,同时希望能给新上手此框架的同学提供一些参考作用. 1.Table对接后台返回数据 针对Table数据格式与后他接口返回数据格

  • .NET+PostgreSQL实践与避坑指南(推荐)

    简介 .NET+PostgreSQL(简称PG)这个组合我已经用了蛮长的一段时间,感觉还是挺不错的.不过大多数人说起.NET平台,还是会想起跟它"原汁原味"配套的Microsoft SQL Server(简称MSSQL),其实没有MSSQL也没有任何问题,甚至没有Windows Server都没问题,谁说用.NET就一定要上微软全家桶?这都什么年代了-- PG和MSSQL的具体比较我就不详细展开了,自行搜一下,这种比较分析文章很多.应该说两个RDBMS各有特色,MSSQL工具集庞大(大

  • ant design vue datepicker日期选择器中文化操作

    按照ant design vue官方说明,使用日期选择器需要在入口文件(main.js)全局设置语言: // 默认语言为 en-US,如果你需要设置其他语言,推荐在入口文件全局设置 locale import moment from 'moment'; import 'moment/locale/zh-cn'; moment.locale('zh-cn'); <a-date-picker :defaultValue="moment('2015-01-01', 'YYYY-MM-DD')&q

  • 解决ant design vue中树形控件defaultExpandAll设置无效的问题

    页面步骤: 1.设置a-tree标签 2.默认的treeNodes值设置为空数组 3.在mounted组件加载的时候给treeNodes的值赋值 结果: 设置defaultExpandAll无效,并不能展开所有节点 原因: defaultExpandAll 仅在组件第一次渲染时有效,不仅仅tree组件,其它组件的defaultXXX值都是这个行为, 可以自行搜索受控组件/非受控组件的概念.如果你想异步获取数据后展开全部结点,可以使用非受控方式: https://codepen.io/lovefe

  • ant design vue中表格指定格式渲染方式

    注意点:定义的columns一定要写在data中,否则在加载过程中由于渲染顺序会导致其中的渲染函数无法识别 渲染方法1: 指定渲染函数: const columns = [ { title: '排名', dataIndex: 'key', customRender: renderContent // 渲染函数的规则 }, { title: '搜索关键词', dataIndex: 'keyword', customRender: (text, row, index) => { if (index

  • ant design vue 表格table 默认勾选几项的操作

    为什么我同样的功能要用react .vue 都写一遍 ? 啊我真是不是闲的蛋疼啊(- o -)~zZ 在 ant design vue 中,表格的第一列是联动的选择框 截一张官方文档图,图示最后一排就是禁用状态 点击 checkbox 会触发onChange , 从而得到selectedRowKeys,selectedRowKeys就是选中的 key 数组. onChange: (selectedRowKeys, selectedRows) => { console.log(`selectedR

  • Java多线程基本概念以及避坑指南

    目录 前言 1. 多线程基本概念 1.1 轻量级进程 1.2 JMM 1.3 Java中常见的线程同步方式 2. 避坑指南 2.1. 线程池打爆机器 2.2. 锁要关闭 2.3. wait要包两层 2.4. 不要覆盖锁对象 2.5. 处理循环中的异常 2.6. HashMap正确用法 2.7. 线程安全的保护范围 2.8. volatile作用有限 2.9. 日期处理要小心 2.10. 不要在构造函数中启动线程 End 前言 多核的机器,现在已经非常常见了.即使是一块手机,也都配备了强劲的多核处

  • Ant Design Vue 走马灯实现单页多张图片轮播效果

    最近的项目有个需求是,这种单页多图一次滚动一张图片的轮播效果,项目组件库是antd 然而用了antd的走马灯是这样子的 我们可以看到官网给的api是没有这种功能,百度上也多是在css上动刀,那样也就毕竟繁琐了,我们是什么?我们是程序猿啊,程序猿就该有程序猿的样子,怎么能写繁琐的东西呢,那还怎么为公司项目提高效率!!!(我哪敢说是为了摸鱼啊) 为了追求摸鱼的真谛我仔细查阅了文档https://github.com/vueComponent/ant-design-vue/blob/master/co

  • Vxe-Table开发中的各种坑以及避坑指南

    目录 背景: 开发阶段遇到的各种问题 全局size的问题 按钮的问题 合并单元格的问题 reload和load的问题 总结 背景: 由于公司要开发erp,采用了element-plus做为UI基础框架,但是回想往事点点滴滴,element-ui表格的种种表现令人痛心,于是跟leader商量之后决定使用Vxe-Table做表格插件,虽然element-plus在表格上也在大力优化,但就目前来看可用度确实不高,刚出了一个虚拟滚动,但看上去确实让人有点心急... 开发阶段遇到的各种问题 全局size的

  • Ant Design Vue中的table与pagination的联合使用方式

    目录 Ant Design Vue中table与pagination联合使用 ant.design.vue中table的使用说明 table的创建 table之columns table之dataSource table之loading table之scroll table之rowKey table之rowSelection table之customRow table之change Ant Design Vue中table与pagination联合使用 表格table使用链接:ant desig

随机推荐