溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

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

發(fā)布時間:2020-10-07 18:56:11 來源:腳本之家 閱讀:281 作者:劉家三胖 欄目:web開發(fā)

ant-design-vue是螞蟻金服 Ant Design 官方唯一推薦的Vue版UI組件庫,它其實是Ant Design的Vue實現(xiàn),組件的風格與Ant Design保持同步,組件的html結構和css樣式也保持一致。 用下來發(fā)現(xiàn)它的確稱得上為數不多的完整的VUE組件庫與開發(fā)方案集成項目。

本文主要目的是總結一些開發(fā)過程中比較耗時間去查找,文檔中沒有具體說明的常見問題,同時希望能給新上手此框架的同學提供一些參考作用。 

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' }
  }

多嘗試后發(fā)現(xiàn),其實只要不配置dataIndex就好了。。。slot-scope自定義一個字段,自然就拿到了整行數據

3.table分頁組件展示條數

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

4.神奇的最后一個標簽隱藏問題

使用可編輯tags過程中值得注意的問題,一般刪除某個tag不止是從DOM中刪除這個tag,而是需要調接口修改數據,那么這時候如果選擇用修改完的數據動態(tài)渲染tag列表,并且理所當然地認為動態(tài)綁定數據就不需要關心數據手動處理,問題就出現(xiàn)了:

假如一共有5個tag,現(xiàn)在刪除第一個tag,并調用接口返回新數據,注意tags默認的刪除操作也不是從DOM中刪除這個tag,而是將這個tag設置為```display:none```!這就導致了一個很神奇的問題,此時新返回的tags數組長度已經 -1,而它仍然認為當前列表的第一個Tag是隱藏的,最后呈現(xiàn)的效果就是只剩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>

這個問題貌似沒什么好的辦法,只能放棄綁定動態(tài)數據,判斷接口調用成功后,再用文檔中的手動操作增減數據的辦法:

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

5.表單的各種常規(guī)操作

單獨觸發(fā)某個字段的校驗:

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(); //創(chuàng)建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的實現(xiàn)不夠了解。

還是在`@/src/utils/request.js`,這里創(chuàng)建了axios實例供全局調用,根據axios文檔,**在創(chuàng)建** axios 實例時添加:`withCredentials: true`

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

結果發(fā)現(xiàn)接口請求仍然不帶cookie,無奈試了一下用fetch請求`fetch(url, { credentials: 'include', mode: 'cors' })`,發(fā)現(xiàn)可以攜帶cookie,百思不得其解,兩者都是基于promise實現(xiàn)的,但是fetch在寫法和攔截請求響應等方面都比較麻煩,全部替換成fetch也不太現(xiàn)實。最后才發(fā)現(xiàn),是mock.js沒有注釋(`main.js`中注釋掉就好了),原來mock.js是通過攔截XHR請求來實現(xiàn)的接口模擬,Axios本質上也是對原生XHR的封裝,只不過它是Promise的實現(xiàn)版本,所以它當然被攔截了,而fetch脫離了XHR,這也是fetch請求能正常攜帶cookie的原因,這里還沒有全部梳理清楚,打算在后一篇中詳細介紹一下

7.單點登錄的實現(xiàn)

全局的路由鉤子在`permission.js`中,一般單點登錄、權限驗證都是在這里處理,這里也不例外。沒什么特別的,需要注意的一點就是,不要忘記對頁面其他接口的統(tǒng)一無權限處理,和403請求的響應處理。同時畫個流程圖會更快一些,這里就記錄一下吧:

流程圖:

ant-design-vue 快速避坑指南(推薦)路由鉤子

路由鉤子的處理:

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`中接口返回的統(tǒng)一處理:

service.interceptors.response.use((response) => {
  if (response.data.status === 1005){
      //... 同上跳去登陸頁
  }else{
    //為返回數據做統(tǒng)一處理
    return response.data
  }
}, err) 

7.引入eCharts

1)npm install

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

3) resize觸發(fā)圖表自適應

echart有resizeAPI,一般是在圖表組件如barChart.vue里面手動監(jiān)聽窗口resize

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

后面借鑒element-admin, 利用mixins實現(xiàn)了更完善的統(tǒng)一處理方法:

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() {
  // 據上一次觸發(fā)時間間隔
  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監(jiān)聽方法混入圖表組件即可

mixins: [resize]

總結

以上所述是小編給大家介紹的ant-design-vue 快速避坑指南,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對億速云網站的支持!
如果你覺得本文對你有幫助,歡迎轉載,煩請注明出處,謝謝!

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI