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 = '-' }) }) }, }