elementui已經封裝好了 el-table 組件,只須要指定 data 數據源便可,所以一般在 vue 實例生命週期的 created 階段,從數據庫獲取數據,再將返回的數據綁定到 data
若是後端同窗能直接返回前端須要展現的全部數據,那麼前端只須要請求一次,多麼的和諧,多麼完美。
然而凡事皆有例外,好比在已有的table表格增長若干列,而數據從不一樣的源獲取,這時候再修改功能已經完善的接口顯然不明智,那麼前端使用同步或異步請求來獲取數據是比較好的方案。前端
例如一個文章接口只返回了文章id、做者、內容、建立時間等信息,而前端須要展現做者暱稱、簽名等,這些信息要從另外一個接口獲取。
解決方式vue
典型應用: 由promise 鏈式調用,當所有請求成功後再展現內容,任一步驟失敗則請求的數據不完整,視爲請求失敗。數據庫
<el-table v-loading="listLoading" :data="list" border fit > <el-table-column label="暱稱" min-width="100" align="center"> <template slot-scope="scope"> <span v-if="userInfo[scope.row.author]">{{ userInfo[scope.row.author].nickname }}</span> <span v-else> - </span> </template> </el-table-column>
created() { this.getList() }, methods: { getList() { // 先獲取帖子信息,再根據帖子信息查找用戶信息和帖子詳情 this.listLoading = true // 很重要,在全部數據返回前,頁面要一直顯示 loading let list = [] let total = 0 getArticleListApi(this.listQuery) .then(response => { list = response.data.items total = response.data.total return this.getAuthorInfo(list) }) .then(() => { this.list = list this.total = total // 這裏成功獲取了做者信息, loading 結束 this.listLoading = false }) .catch(err => { this.listLoading = false if(err === 'CANCELD_BY_USER'){ return } FetchDataNotifyWarning(err, 3) }) }, // 獲取用戶信息 getAuthorInfo(list){ // 根據用戶ID獲取暱稱、個性簽名、賬號狀態等信息 const _this = this let users = new Set(list.map(v => v.author)) let promises = [] function promiseFunc(id){ return new Promise((resolve, reject) => { getAccountInfoApi(id) .then(resp => { _this.userInfo[id] = resp.data.data resolve() }) .catch(err => { // 忽略可能獲取不到用戶的錯誤 resolve() }) }) } users.forEach(id => { if(id){ promises.push(promiseFunc(id)) } }) return Promise.all(promises) }, }
典型應用: 先展現全部文章信息,每一行增長一個鏡像字段,如: _async_label ,請求成功後更新該字段內容,失敗則更新爲特定字符,如 '-' 。後端
<el-table-column label="標籤" min-width="100" align="center"> <template slot-scope="scope"> <span>{{ scope.row._async_label }}</span> </template> </el-table-column>
methods: { getList() { this.listLoading = true this.fetchData(this.listQuery) .then(response => { let tablist = response.data.items let total = response.data.total // 異步顯示文章標籤 tablist.forEach(item => { item._async_label = '' }) this.list = tablist this.total = total this.getLabel() // 這裏 loading 結束,頁面上能夠看到表格了 this.listLoading = false }) .catch(err => { this.$notify.warning({ message: err || '未獲取到相關信息,請刷新頁面或稍候再試', duration: 3 * 1000, }) this.listLoading = false }) }, // 獲取 文章標籤 getLabel(){ this.list.forEach(item => { getArticleLabelApi(item.articleId) .then(resp => { item._async_label = resp.data.val }) .catch(()=>{ item._async_label = '-' }) }) }, }