Ant Design Vue quick avoidance Guide (recommended)

Time:2020-2-25

Ant Design Vue is the only Vue version of UI component library recommended by ant design. It is actually the Vue implementation of ant design. The style of the component is synchronized with ant design, and the HTML structure and CSS style of the component are consistent. It is found that it is indeed a few complete Vue component library and development solution integration projects.

The main purpose of this paper is to summarize some common problems that take time to find in the development process, which are not specifically described in the document, and hope to provide some reference for the new students.  

1. Data returned by table docking with background

In view of the inconsistency between the table data format and the data format returned by other interfaces, modify the ‘@ / components / table / index. JS’ starting from line 132

It is OK to modify the pageno, PageSize, totalcount, data fields to be consistent with the background return fields

result.then(r => {
 this.localPagination = Object.assign({}, this.localPagination, {
  Current: r.pageno, // modify the current page field here
  Total: r.totalcount, // modify the total record field here
  showSizeChanger: this.showSizeChanger,
  pageSize: (pagination && pagination.pageSize) ||
   This. Localpagination. PageSize // modify the current page field of the total number of records here
 })
  //r. Data in data is modified to return list field
 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 // returns the array data in the result
 this.localLoading = false
});

2. Table operation bar parameters

Each data specified in table’s datasource must contain an object with name as key, and the displayed data is the data corresponding to the corresponding key. Dataindex is used to declare the key corresponding to the column data in the data item

However, in the operation column, we usually need to pass in unknown data. Try configuring dataindex as shown in the figure below. The data cannot be passed into slot scope correctly

columns: [
  ...
  {
      Title: 'operation',
      dataIndex: 'id,text',
      key: 'id',
      scopedSlots: { customRender: 'operation' }
  }

After many attempts, I found that as long as dataindex is not configured… If you customize a field in slot scope, you will get the whole row of data

3. Number of table paging components

: pagination = "{showtotal: total = > ` total ${total} items'}"

4. Magic last tag hiding problem

In the process of using editable tags, we should pay attention to the following problems: generally, deleting a tag is not only to delete the tag from DOM, but also to adjust the interface to modify the data. At this time, if we choose to dynamically render the tag list with the modified data, and naturally think that the dynamic binding data does not need to care about the manual processing of the data, the problem arises:

If there are 5 Tags in total, now delete the first tag and call the interface to return new data. Note that the default deletion of tags is not to delete the tag from DOM, but to set the tag to ` ` display: none ` ‘. This leads to a very magical problem. At this time, the length of the newly returned tags array has already been -1. It still thinks that the first tag in the current list is hidden, and the final rendering effect is that there are only three tags left. At this time, delete the first tag (actually the second), and then there is only one tag left..


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

There seems to be no good way to solve this problem. We can only give up binding dynamic data, judge the success of the interface call, and then use the manual operation in the document to increase or decrease the data


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

5. Various routine operations of forms

Trigger the verification of a field separately:


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

Clear the value of a field:

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

Set the initial value of the form:

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

Note: uninitialized values use undefined instead of ‘; otherwise, the drop-down box will not display placeholder!

Action function for user-defined file upload:

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

upLoad (info) {
  let file = info.file;
  Let param = new formdata(); // create a form object
  Param. Append ('File ', file); // add data to form object through append
  Console.log (param. Get ('File '); // formdata private class object cannot be accessed. You can judge whether the value is passed in through get
  let config = {
    headers:{'Content-Type':'multipart/form-data'}
  }; 
  this.$http.post(url, param, config).then(res => {
    ...
  })
},

6. The problem of carrying cookies across domains

When doing single sign on, you need to carry cookies in the request header. The actual reason is that you don’t know enough about the implementation of mock.js.

Or in ‘@ / SRC / utils / request. JS’. Here, an Axios instance is created for global calls. According to the Axios document, * * when creating an * * Axios instance, add: ` with credentials: true`


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

The results show that the interface request still does not have cookies, but I tried to use the fetch request ‘fetch (URL, {credentials:’ include ‘, mode:’ CORS’} ‘to find that cookies can be carried, which is impossible to understand. Both of them are based on promise, but the write method and blocking request response of the fetch are relatively troublesome, and it is not realistic to replace all of them with a fetch. Finally, it is found that mock.js has no comment (` main. JS’ has no comment). Originally, mock.js is an interface simulation implemented by intercepting XHR requests. Axios is essentially an encapsulation of native XHR, but it is the implementation version of promise, so of course, it is intercepted, and fetch is separated from XHR, which is the reason why fetch requests can carry cookies normally. There is no cookie here All of them are sorted out. I plan to introduce them in detail in the next article

7. Implementation of single sign on

The global routing hook is in ‘permission. JS’. Generally, single sign on and permission verification are handled here, and this is no exception. It’s nothing special. One thing to note is that don’t forget to handle other interfaces of the page uniformly without permission and 403 request response. It will be faster to draw a flow chart at the same time. Let’s record it here:

Flow chart:

Routing hook

Processing of routing hooks:

router.beforeEach((to, from, next) => {
 //Processing without permission for 403
 if (to.path === '/403') {
  next()
 } else {
  If (roles) {// logged in
   next()
  } else {
      //To obtain user information, getUserInfo logic is as follows:
      //Status = 403 & & reject (RES), return containing status;
      //Status = 1005 & & reject (res.data) returns the URL of redirection;
      //status=1000 && resolve()
   store
    .dispatch('GetUserInfo') 
    .then(res => {
     next()
    })
    .catch((e) => {
     if (e.status) {
      next({ path: '/403' })
     } else {
            //Connect the URL to skip to the login page. If the login succeeds, it will be redirected back to the current page
      const url = e.substring(0, e.lastIndexOf('redirect')) + 'redirect=' + login_redirect
      window.location.href = url
     }
    })
  }
 }
})

`@/Unified processing of interface return in Src / utils / request. JS’:

service.interceptors.response.use((response) => {
  if (response.data.status === 1005){
      //... ditto to landing page
  }else{
    //Unified processing of returned data
    return response.data
  }
}, err)

7. Introduce echarts

1)npm install

2) Under components, create barchart.vue, import ecrats from ‘ecrats’, normal operation

3) Resize trigger chart adaption

Echart has a resize API, which is usually used to manually monitor the window resize in chart components such as barchart.vue


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

Later, we use element admin for reference, and use mixins to realize a more complete unified processing method:

1) Define a mixin: resize.js

Import {debounce} from '@ / utils' // anti shake function
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 add anti shake function

export const debounce = (func, wait, immediate) => {
 let timeout, args, context, timestamp, result
 const later = function() {
  //According to the last trigger interval
  const last = +new Date() - timestamp
  //Last called time interval of wrapped function last is less than set time interval wait
  if (last < wait && last > 0) {
   timeout = setTimeout(later, wait - last)
  } else {
   timeout = null
   //If it is set to immediate = = true, because the start boundary has already been called, there is no need to call here
   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 the delay does not exist, reset the delay
  if (!timeout) timeout = setTimeout(later, wait)
  if (callNow) {
   result = func.apply(context, args)
   context = args = null
  }
  return result
 }
}

3) The resize listening method can be mixed into the chart component

mixins: [resize]

summary

The above is the ant design Vue quick escape guide introduced by Xiaobian to you. I hope it can help you. If you have any questions, please leave me a message and Xiaobian will reply to you in time. Thank you very much for your support of the developepaer website!
If you think this article is helpful to you, welcome to reprint, please indicate the source, thank you!