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

elementui已經封裝好了 el-table 組件,只須要指定 data 數據源便可,所以一般在 vue 實例生命週期的 created 階段,從數據庫獲取數據,再將返回的數據綁定到 data
若是後端同窗能直接返回前端須要展現的全部數據,那麼前端只須要請求一次,多麼的和諧,多麼完美。
然而凡事皆有例外,好比在已有的table表格增長若干列,而數據從不一樣的源獲取,這時候再修改功能已經完善的接口顯然不明智,那麼前端使用同步或異步請求來獲取數據是比較好的方案。前端

同步

例如一個文章接口只返回了文章id、做者、內容、建立時間等信息,而前端須要展現做者暱稱、簽名等,這些信息要從另外一個接口獲取。
解決方式vue

  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 = '-'
      })
    })
  },
}
相關文章
相關標籤/搜索