Ant-Design-Vue快速上手指南+排坑

前言

公司要开发一个后台管理系统,对于UI库的选择上选择了颜值爆表的Ant-Design-Vue做为整个项目UI库,但谁曾想,暗中的坑一个接一个,文档也不怎么详细,可能习惯了element-ui的掘友们也许不怎么好适应,本文就带你们一块儿学习如何高效使用Ant-Design-Vuejavascript

NO.1 表单组件

首先就来讲说最经常使用的Form组件的正确使用姿式:css

先来看官方一段话述:html

第1、咱们不推荐在Form中使用双向绑定,同一份数据可能在多处使用,若是使用双向绑定,那么数据的修改会同时同步到各个组件,但这并非咱们想要的, 你应该在表单提交成功或失败或确认时同步数据,使用非双向绑定的表单,你会拥有最大限度的控制数据修改/同步的权限。

第2、若是你不使用表单的自动校验/收集功能,即没有使用v-decorator修饰过的组件,你依然可使用v-model
复制代码

看了官方的建议后,咱们愉快的使用v-decorator修饰input组件,代码以下:vue

<a-form-item>
          <a-input
            placeholder="帐号"
            v-decorator="['account',{rules: [{ required: true,whitespace:true,message: '请输入您的登录帐号' }]}]"
            />
</a-form-item>
复制代码

划重点:java

v-decorator里的account能够理解为input的name值,后面{}对象能够配置校验规则,初始值等参数,这里须要注意的是使用了v-decorator的组件没法使用v-model,也没法设置value等与值有关的属性,不然报错 webpack

v-decorator会自动收集你表单里的数据到form对象里,因此别忘了在data中加上这句代码: form: this.$form.createForm(this)web

模板中这么写:

如何自定义表单校验规则

这里拿确认密码举例:ajax

<a-input
       type="password"
       v-decorator="['new_password',{rules:[{required: true,whitespace:true,message: '请输入新密码'},{validator: handlePass}]}]"
/>
<a-input
        type="password"
        v-decorator="['confirm_password',{rules:[{required: true,whitespace:true,message: '请重复新密码'},{validator:handleConfirmPass}]}]"
/>
复制代码

这里咱们使用validator校验器自定义函数element-ui

handlePass(rule, value, callback) {
      this.password = value;
      callback();
},
handleConfirmPass(rule, value, callback) {
      if (this.password && this.password !== value) {
           callback('与新密码输入不一致');
      }
      callback();
},
复制代码

这里须要注意callback()必须调用后端

这里的value就是对应表单输入了的值,而后知道了这些咱们就能够写咱们本身的业务逻辑了

作好的效果如图:

表单回显

咱们在作编辑时首先须要经过后端接口读取到以前的数据,可是由于如今没有了v-model,那么咱们该怎么办?

能够调用form对象中的setFieldsValue把后端返回的对象直接设置上去,若是是在mounted方法里必须加上$nextTick,否则会抛出警告说咱们在表单未渲染好以前给予了数据

代码如图:

图中setFieldsInitialValue是设置表单初始值,若是表单中有重置按钮,就须要设置上,重置按钮调用this.form.resetFields()就能够重置form表单了

这个setFieldsValue方法会把传进去的对象的key和模板中v-decorator中的第一个参数比较,会自动把对应的值set进去。

提交表单

按钮加上html-type="submit"后点击会触发这个方法,这个方法校验表单中全部必填项没有问题后会自动帮咱们把表单中全部带有v-decorator修饰的组件的值和name序列化好,咱们就能够直接传给后端了。

NO.2 表格(Table)

咱们的模板能够这么写:

ant-design-vue的表格自带分页,接下来我把上图中的参数挨个解释下,columns是单元格信息,咱们能够把他导出为一个数组,以下图:

这里的title是用户看到的文字,dataIndex要和后台传过来的字段一致,否则数据不会显示出来,其次还提供了customRender和scopedSlots两种方式自定义内容,这里使用了第一种方式,但值得一提的是若是使用的是slot-scope方式,在模板中定义一个点击事件,想要获取到当前行的数据时,必定必定不要加dataIndex属性,不然会是undefined

看一个scopedSlots使用的例子:

能够看到上面定义columns时给action没有加dataIndex

咱们继续看dataSource是什么,他就是你给table传递的数据

rowKey能够理解为时循环时须要的key(必有)

pagination初始化一个空对象

scroll定义表格能够横向滚动

handleTableChange是当分页数据发生改变时抛出的事件

为了简化操做,我这里封装了一个mixin,当页面中有table时直接混入mixin就支持分页和拉取数据的逻辑了,代码以下:

export const mixin = {
  data() {
    return {
      pagination: {},
      data: [],
    };
  },
  methods: {
    handleTableChange(pagination) {
      const pager = {...this.pagination};
      pager.current = pagination.current;
      this.pagination = pager;
      this.loadData({
        page: pagination.current
      });
    },
    async loadData(params = {}) {
      try {
        const {data: table_data, total, per_page} = await this.loadMethod('flush' in params ? {page: 1} : {page: 1, ...params});
        const pagination = {...this.pagination};
        pagination.total = total;
        pagination.pageSize = per_page;
        'flush' in params && (pagination.current = 1);
        this.data = table_data;
        this.pagination = pagination;
      } catch (e) {
        console.log(e);
      }
    }
  }
};
复制代码

flush用于标识是不是插入新数据或者删除了数据,若是是咱们直接把page重置为1返回第一页 咱们在页面使用只须要如下几行代码:

import { getLog } from '@/api/api';
import { mixin } from '@/mixins';
export default {
  name: "log",
  mixins: [mixin],
  data() {
    return {
      columns,
      loadMethod: getLog
    };
  },
  mounted() {
    this.loadData();
  }
};

复制代码

这样其余相似的组件也能够直接复用本逻辑。

NO.3 Spin组件

咱们平时在后台管理系统中,ajax请求过程当中都会出现全屏加载提示的遮罩层,作这个功能时我想到了这个组件,而后去官方文档查看,看到了以下图的操做方式:

而后粘贴到代码中,各类操做,没有任何反应,甚至有时候还来点小报错,Spin组件确定是引入了,反正就是最后怎么操做都没成功,无奈之下,本身用了他的样式写了个Vue的Spin插件:

咱们首先新建Loading.vue

<template>
  <div v-if="show" class="loading-container">
    <div class="loading-mask"></div>
    <div class="loading-content">
      <a-spin tip="正在加载数据中..." size="large">
      </a-spin>
    </div>
  </div>
</template>
<script>
export default {
  name: 'Loading',
  props: {
    show: Boolean,
  },
  data() {
    return {
    }
  }
}
</script>
<style lang="scss" scoped>
  .loading-container{
    position: relative;
    text-align: center;
    z-index:9999;
    .loading-mask{
      position: fixed;
      top:0;
      bottom:0;
      left:0;
      right:0;
      background-color:rgba(0,0,0,.7);
    }
    .loading-content{
      position: fixed;
      left: 50%;
      top: 50%;
      z-index: 300;
      transform: translate(-50%,-50%);
      text-align: center;
      color:#fff;
    }
  }
</style>

复制代码

而后再新建Loading.js

import Vue from 'vue';
import loadingComponent from './Loading.vue';

const LoadingConstructor = Vue.extend(loadingComponent);

const instance = new LoadingConstructor({
  el: document.createElement('div')
});

instance.show = false; // 默认隐藏
const loading = {
  show() { // 显示方法
    instance.show = true;
    document.body.appendChild(instance.$el);
  },
  hide() { // 隐藏方法
    instance.show = false;
  }
};

export default {
  install() {
    if (!Vue.$loading) {
      Vue.$loading = loading;
    }
    Vue.mixin({
      created() {
        this.$loading = Vue.$loading;
      }
    });
  }
};

复制代码

而后在main.js中

import loading from '@/components/Loading/loading.js';

Vue.use(loading);
复制代码

而后咱们就能够愉快的调用了:

Vue.$loading.show();
复制代码

打包优化

首先就是用官方快速上手中提供的按需加载,这里再也不赘述,使用以后还存在如下问题:

里面的moment.js,还有lodash,还有icon的dist竟然占用了咱们500KB的空间,这不能忍,那怎么办呢?

new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/),
复制代码

咱们首先忽略掉语言包,而后看看图标怎么优化:

config.resolve.alias
      .set('@', resolve('src'))
      .set('@ant-design/icons/lib/dist$',resolve('src/icon.js'))
复制代码

咱们还须要在src文件夹下面加一个文件 icons.js

//本身项目里面用到的Icon
export {default as UserOutline} from '@ant-design/icons/lib/outline/UserOutline';
export {default as CloseCircleFill} from '@ant-design/icons/lib/fill/CloseCircleFill';
export {default as InfoCircleFill} from '@ant-design/icons/lib/fill/InfoCircleFill';
export {default as CheckCircleFill} from '@ant-design/icons/lib/fill/CheckCircleFill';
复制代码

咱们还能够开启gzip压缩等,使用DLL优化咱们的打包速度,这些在这里就再也不赘述了,社区有不少相似的贴子。

结语

那么对于ant-design-vue使用的前两天感受不怎么顺手,如今只能说真香

其实这个UI库用习惯以后会发现好像Form表单的设计其实比v-model更好用,哈哈, 以为不错的能够点波关注👍

相关文章
相关标签/搜索