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更好用,哈哈, 以爲不錯的能夠點波關注👍

相關文章
相關標籤/搜索