ant-design-vue 快速避坑指南(推薦)
ant-design-vue是螞蟻金服 Ant Design 官方唯一推薦的Vue版UI組件庫(kù),它其實(shí)是Ant Design的Vue實(shí)現(xiàn),組件的風(fēng)格與Ant Design保持同步,組件的html結(jié)構(gòu)和css樣式也保持一致。 用下來(lái)發(fā)現(xiàn)它的確稱得上為數(shù)不多的完整的VUE組件庫(kù)與開發(fā)方案集成項(xiàng)目。
本文主要目的是總結(jié)一些開發(fā)過(guò)程中比較耗時(shí)間去查找,文檔中沒(méi)有具體說(shuō)明的常見(jiàn)問(wèn)題,同時(shí)希望能給新上手此框架的同學(xué)提供一些參考作用。
1.Table對(duì)接后臺(tái)返回?cái)?shù)據(jù)
針對(duì)Table數(shù)據(jù)格式與后他接口返回?cái)?shù)據(jù)格式不一致問(wèn)題,修改 `@/components/table/index.js` 132行起
主要修改pageNo,pageSize,totalCount,data這字段與后臺(tái)返回字段一致就OK了
result.then(r => { this.localPagination = Object.assign({}, this.localPagination, { current: r.pageNo, // 這里修改當(dāng)前分頁(yè)字段 total: r.totalCount, // 這里修改總記錄數(shù)字段 showSizeChanger: this.showSizeChanger, pageSize: (pagination && pagination.pageSize) || this.localPagination.pageSize // 這里修改總記錄數(shù)當(dāng)前頁(yè)數(shù)字段 }) //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 // 返回結(jié)果中的數(shù)組數(shù)據(jù) this.localLoading = false });
2.table操作欄參數(shù)問(wèn)題
在table的dataSource中指定的每一個(gè)數(shù)據(jù)中,都必須包含有name為key的對(duì)象,而顯示出的數(shù)據(jù)就是相應(yīng)key對(duì)應(yīng)的數(shù)據(jù),dataIndex就用來(lái)聲明列數(shù)據(jù)在數(shù)據(jù)項(xiàng)中對(duì)應(yīng)的key
然而在操作列中,我們一般需要傳入不知一項(xiàng)數(shù)據(jù),試了一下如下圖配置dataIndex,數(shù)據(jù)并不能正確傳入slot-scope中
columns: [ ... { title: '操作', dataIndex: 'id,text', key: 'id', scopedSlots: { customRender: 'operation' } }
多嘗試后發(fā)現(xiàn),其實(shí)只要不配置dataIndex就好了。。。slot-scope自定義一個(gè)字段,自然就拿到了整行數(shù)據(jù)
3.table分頁(yè)組件展示條數(shù)
:pagination="{showTotal: total => `共${total}條`}"
4.神奇的最后一個(gè)標(biāo)簽隱藏問(wèn)題
使用可編輯tags過(guò)程中值得注意的問(wèn)題,一般刪除某個(gè)tag不止是從DOM中刪除這個(gè)tag,而是需要調(diào)接口修改數(shù)據(jù),那么這時(shí)候如果選擇用修改完的數(shù)據(jù)動(dòng)態(tài)渲染tag列表,并且理所當(dāng)然地認(rèn)為動(dòng)態(tài)綁定數(shù)據(jù)就不需要關(guān)心數(shù)據(jù)手動(dòng)處理,問(wèn)題就出現(xiàn)了:
假如一共有5個(gè)tag,現(xiàn)在刪除第一個(gè)tag,并調(diào)用接口返回新數(shù)據(jù),注意tags默認(rèn)的刪除操作也不是從DOM中刪除這個(gè)tag,而是將這個(gè)tag設(shè)置為```display:none```!這就導(dǎo)致了一個(gè)很神奇的問(wèn)題,此時(shí)新返回的tags數(shù)組長(zhǎng)度已經(jīng) -1,而它仍然認(rèn)為當(dāng)前列表的第一個(gè)Tag是隱藏的,最后呈現(xiàn)的效果就是只剩3個(gè)Tag,此時(shí)再接著刪除第一個(gè)tag(其實(shí)是第二個(gè)),那么就只剩1個(gè)tag了。。
<a-tag v-for="(tag, index) in Tags" :key="tag.id" :closable="tagCloseable" :afterClose="() => handleTagStatus(0,tag)" >{{ tag.name }} </a-tag>
這個(gè)問(wèn)題貌似沒(méi)什么好的辦法,只能放棄綁定動(dòng)態(tài)數(shù)據(jù),判斷接口調(diào)用成功后,再用文檔中的手動(dòng)操作增減數(shù)據(jù)的辦法:
this.Tags = this.Tags.filter(tag => tag.id !== removeTag.id)
5.表單的各種常規(guī)操作
單獨(dú)觸發(fā)某個(gè)字段的校驗(yàn):
this.form.validateFields(['name'], { force: true })
清除某個(gè)字段的值:
this.form.resetFields(`name`,'')
設(shè)置表單初始值:
this.form.resetFields(`name`,'')
注意:不初始化的值用undefined而非‘',否則下拉框會(huì)不顯示placeholder!
自定義文件上傳的action函數(shù):
<a-upload :customRequest="upLoad"></a-upload> upLoad (info) { let file = info.file; let param = new FormData(); //創(chuàng)建form對(duì)象 param.append('file',file);//通過(guò)append向form對(duì)象添加數(shù)據(jù) console.log(param.get('file')); //FormData私有類對(duì)象訪問(wèn)不到,可以通過(guò)get判斷值是否傳進(jìn)去 let config = { headers:{'Content-Type':'multipart/form-data'} }; this.$http.post(url, param, config).then(res => { ... }) },
6.接口跨域攜帶cookie問(wèn)題
做單點(diǎn)登錄時(shí)需要在請(qǐng)求頭中攜帶cookie,遇到了很坑人的問(wèn)題,實(shí)際原因是對(duì)mock.js的實(shí)現(xiàn)不夠了解。
還是在`@/src/utils/request.js`,這里創(chuàng)建了axios實(shí)例供全局調(diào)用,根據(jù)axios文檔,**在創(chuàng)建** axios 實(shí)例時(shí)添加:`withCredentials: true`
const service = axios.create({ baseURL: `${process.env.VUE_APP_BASEURL}/backend`, withCredentials: true, timeout: 6000 })
結(jié)果發(fā)現(xiàn)接口請(qǐng)求仍然不帶cookie,無(wú)奈試了一下用fetch請(qǐng)求`fetch(url, { credentials: 'include', mode: 'cors' })`,發(fā)現(xiàn)可以攜帶cookie,百思不得其解,兩者都是基于promise實(shí)現(xiàn)的,但是fetch在寫法和攔截請(qǐng)求響應(yīng)等方面都比較麻煩,全部替換成fetch也不太現(xiàn)實(shí)。最后才發(fā)現(xiàn),是mock.js沒(méi)有注釋(`main.js`中注釋掉就好了),原來(lái)mock.js是通過(guò)攔截XHR請(qǐng)求來(lái)實(shí)現(xiàn)的接口模擬,Axios本質(zhì)上也是對(duì)原生XHR的封裝,只不過(guò)它是Promise的實(shí)現(xiàn)版本,所以它當(dāng)然被攔截了,而fetch脫離了XHR,這也是fetch請(qǐng)求能正常攜帶cookie的原因,這里還沒(méi)有全部梳理清楚,打算在后一篇中詳細(xì)介紹一下
7.單點(diǎn)登錄的實(shí)現(xiàn)
全局的路由鉤子在`permission.js`中,一般單點(diǎn)登錄、權(quán)限驗(yàn)證都是在這里處理,這里也不例外。沒(méi)什么特別的,需要注意的一點(diǎn)就是,不要忘記對(duì)頁(yè)面其他接口的統(tǒng)一無(wú)權(quán)限處理,和403請(qǐng)求的響應(yīng)處理。同時(shí)畫個(gè)流程圖會(huì)更快一些,這里就記錄一下吧:
流程圖:
路由鉤子
路由鉤子的處理:
router.beforeEach((to, from, next) => { // 對(duì)403無(wú)權(quán)限的處理 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跳去登陸頁(yè),登陸成功會(huì)重定向回當(dāng)前頁(yè)(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){ //... 同上跳去登陸頁(yè) }else{ //為返回?cái)?shù)據(jù)做統(tǒng)一處理 return response.data } }, err)
7.引入eCharts
1)npm install
2) components下新建barChart.vue ,import echarts from 'echarts',正常操作...
3) resize觸發(fā)圖表自適應(yīng)
echart有resizeAPI,一般是在圖表組件如barChart.vue里面手動(dòng)監(jiān)聽(tīng)窗口resize
mounted() { window.addEventListener("resize", () => { this.chart.resize(); }); },
后面借鑒element-admin, 利用mixins實(shí)現(xiàn)了更完善的統(tǒng)一處理方法:
1)定義一個(gè)mixin:resize.js
import { debounce } from '@/utils'//防抖函數(shù) 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中添加防抖函數(shù)
export const debounce = (func, wait, immediate) => { let timeout, args, context, timestamp, result const later = function() { // 據(jù)上一次觸發(fā)時(shí)間間隔 const last = +new Date() - timestamp // 上次被包裝函數(shù)被調(diào)用時(shí)間間隔 last 小于設(shè)定時(shí)間間隔 wait if (last < wait && last > 0) { timeout = setTimeout(later, wait - last) } else { timeout = null // 如果設(shè)定為immediate===true,因?yàn)殚_始邊界已經(jīng)調(diào)用過(guò)了此處無(wú)需調(diào)用 if (!immediate) { result = func.apply(context, args) if (!timeout) context = args = null } } } return function(...args) { context = this timestamp = +new Date() const callNow = immediate && !timeout // 如果延時(shí)不存在,重新設(shè)定延時(shí) if (!timeout) timeout = setTimeout(later, wait) if (callNow) { result = func.apply(context, args) context = args = null } return result } }
3)resize監(jiān)聽(tīng)方法混入圖表組件即可
mixins: [resize]
總結(jié)
以上所述是小編給大家介紹的ant-design-vue 快速避坑指南,希望對(duì)大家有所幫助,如果大家有任何疑問(wèn)請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!
如果你覺(jué)得本文對(duì)你有幫助,歡迎轉(zhuǎn)載,煩請(qǐng)注明出處,謝謝!
相關(guān)文章
vue?LogicFlow自定義邊實(shí)現(xiàn)示例詳解
這篇文章主要為大家介紹了vue?LogicFlow自定義邊示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-01-01vueJs函數(shù)toRaw?markRaw使用對(duì)比詳解
這篇文章主要為大家介紹了vueJs函數(shù)toRaw?markRaw使用對(duì)比詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-03-03前端JS也可以連點(diǎn)成線詳解(Vue中運(yùn)用AntVG6)
這篇文章主要給大家介紹了關(guān)于前端JS連點(diǎn)成線(Vue中運(yùn)用?AntVG6)的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2023-01-01Vue實(shí)現(xiàn)搜索結(jié)果高亮顯示關(guān)鍵字
這篇文章主要為大家詳細(xì)介紹了Vue實(shí)現(xiàn)搜索結(jié)果高亮顯示關(guān)鍵字,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-05-05解決在vue的mounted中獲取對(duì)象為null問(wèn)題
這篇文章主要介紹了解決在vue的mounted中獲取對(duì)象為null問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-03-03Vue3.0?axios跨域請(qǐng)求代理服務(wù)器配置方式
這篇文章主要介紹了Vue3.0?axios跨域請(qǐng)求代理服務(wù)器配置方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-04-04Vue3+vantUI3時(shí)間組件封裝過(guò)程支持選擇年以及年月日時(shí)分秒
這篇文章主要介紹了Vue3+vantUI3時(shí)間組件封裝過(guò)程支持選擇年以及年月日時(shí)分秒,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),感興趣的朋友跟隨小編一起看看吧2024-07-07