vue+elementui搭建后台管理界面(8 同步/異步獲取數據渲染table)


elementui已經封裝好了 el-table 組件,只需要指定 data 數據源即可,因此通常在 vue 實例生命周期的 created 階段,從數據庫獲取數據,再將返回的數據綁定到 data
如果后端同學能直接返回前端需要展示的所有數據,那么前端只需要請求一次,多么的和諧,多么完美。
然而凡事皆有例外,比如在已有的table表格增加若干列,而數據從不同的源獲取,這時候再修改功能已經完善的接口顯然不明智,那么前端使用同步或異步請求來獲取數據是比較好的方案。

同步

例如一個文章接口只返回了文章id、作者、內容、創建時間等信息,而前端需要展示作者昵稱、簽名等,這些信息要從另一個接口獲取。
解決方式

  1. 獲取全部文章列表,保存到變量 list
  2. 對 list 的 author 字段去重后發起請求,此請求返回promise
  3. promise 鏈式調用完畢,將 list 綁定到 el-table組件

典型應用: 由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 = '-'
      })
    })
  },
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM