• 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 = '-'
          })
        })
      },
    }
    
  • 相关阅读:
    异常处理 UDP通信
    网络编程 socket套接字 半连接池 通信循环 粘包问题 struct模块 Mac报错
    网络编程 osi七层协议 Time模块补充知识 TCP协议 三次握手 四次挥手
    面向对象 组合 继承
    流式布局
    小程序的瀑布流式布局
    微信小程序的短信接口
    如何高效的编程!
    爱心动画
    em、rpx和px的换算
  • 原文地址:https://www.cnblogs.com/wbjxxzx/p/10338194.html
Copyright © 2020-2023  润新知