vue异步数据呈现方案

demo 地址 源码地址

起因

当我领会到 写程序的重点在于处理好输入与输出之后 再来写一个搜索组件的时候我关于loading 的思考如下
什么时候显示 loading ?
请求发起后还没有到达的这一段时间
怎么控制视图在这段时间内显示 loading ?
使用一个变量来控制
那这个变量属于输入吗?
不算,他是一个输出,这个搜索组件的输入只有一个: searchText
这个输出的相关的 input、 transform 怎么样的?
input:searchText -> transform:异步请求 -> output:loading 状态
怎么实现这样的一个 transform?
这个transform需要立即的返回状态,没有状态页面上无法确定 loading 怎么显示
想到了 promise to object
这个transform需要持续的返回新状态。loading一开始必然是显示,如果之后不返回新状态就没办法关闭了
想到了 vue 的计算属性
想到了事件机制
这个transform还需要返回异步请求的结果。
object 中新增一个 data 字段用来放结果,还可以有一个 error 字段
所以这个 transform 可以当 input 改变时返回一个 object 并且在 依据input发起的异步请求成功或者结束后修改之前返回的 object
然后就是在 vue 中实现这样的一个思路

应用的代码长啥样

typescript
import { defineComponent, ref } from "vue"; import { usePromiseComputed } from "./lib/vue.composition.api"; export default defineComponent({ setup(props, ctx) { const searchText = ref(""); const searchResults = usePromiseComputed({ defaultData: [] as string[], getter() { return searchApi(searchText.value); }, }); return { searchText, searchResults }; }, });
这里的 usePromiseComputed 就是之前思考的 transform ,他返回了一个 ref(object) 然后当 searchText发生变化时会重新执行查询请求searchApi(searchText.value); , 当查询请求结束的时候他会修改之前返回的 ref(object)

在模板中

html
在这里可以看出来 usePromiseComputed 返回的结果其中的五个字段,三个状态字段也就是前文中提到的控制loading的那个变量 两个结果字段

总结

就上面的代码而言是一个极简 input -> tranform -> out 结构。这里不需要手动的声明一个状态变量,然后在不同的阶段在去修改这个变量,这样的操作封装在了 usePromiseComputed 里面。
关于 usePromiseComputed 的实现可以去这里查看https://github.com/2234839/vue-demo/blob/master/src/components/promise-loading/lib/vue.composition.api.ts
实际上针对业务还加入了两个可选参数 deps 和 dataMergeFun
利用 deps 可以显式的声明哪些变量变化的时候重新请求
利用 dataMergeFun 可以非常简单的在上面的代码基础上加入请求结果翻页功能
#文章分享:知乎 思否