在 umi 中使用 dva

在 umi 中使用 dva 就像用 redux 一样

umi 是自带 dva 的,只需要先建一个名为 src/models 的文件夹方便统一管理,然后从 umi 库中取得 getDvaApp 函数

例如,现在有一个数据源,名为 breadcrumb 面包屑,保存面包屑组件的信息

引入 dva

可以这样写 store.ts(可以任意命名,只是我喜欢叫 store)

1
2
3
4
5
6
// models/store.ts
import { getDvaApp } from "umi"

const app = getDvaApp()

app.model(require('./breadcrumb').default)

使用 app.model 注册到全局数据源,注意要通过 .default 取得最终输出

声明初始化

然后声明数据源的格式和内容

1
2
3
4
5
6
// interfaces/Breadcrumb.ts
interface Breadcrumb {
index: number,
pathname: string,
name: string
}
1
2
3
4
5
6
7
8
9
10
11
12
13
// models/breadcrumb.ts
export default {
namespace: 'breadcrumb',
state: [{ index: 0, pathname: '/', name: '首页' }],
reducers: {
info(state: Breadcrumb[], { payload }: { payload: Breadcrumb[] }) {
if (state.length < payload[0].index) {
return state
}
return state.slice(0, payload[0].index).concat([...payload]);
},
},
};

在这里我设计为一个数组,通过数组项来保存面包屑的信息,提交数据变更的时候也要提交数组格式

注意 reducers 中的起名,后续提交变更时,必须使用该起名

注入组件

例如我向 /首页/[版块 id] 这个路径的 [id].tsx 组件注入面包屑数据源

设该组件原本写法如下

1
export default (props: any)=>{}

现在需要写作

1
2
3
4
5
import { connect } from 'umi'

export default connect(
({ breadcrumb }: { breadcrumb: Breadcrumb[] }) => ({ breadcrumb })
)((props: any)=>{})

如上,将数据源连接到组件上

可见,这个 connent 函数,类似于一个立即执行函数

这个立即执行函数要求传入两个参数,第二个是原组件,不赘述了;第一个是要注入的数据源函数,这个函数的传入参数是从全局数据源中获取的数据,返回值是包含该数据的一个对象

传入后,数据会实际绑定在 props 上,如本例可以通过 props.breadcrumb 访问到数据

同时,props 上也会绑定 dispatch 方法,可以通过该方法提交数据变更

注意,不论连接了多少数据,只要有连接数据,就会有 dispatch 函数

提交变更

如上例,提交变更的一个写法如下

1
2
3
4
props.dispatch({
type: 'breadcrumb/info',
payload: [{ index: 0, pathname: '/', name: '首页' }] ,
})

要求提交一个对象,该对象包含至少两个字段

其一是 type,命名格式为 [namespace]/[reducerName],具体要参考你的定义

其二是 payload(也可以是其它名称,取决于你的定义),包含你传入的数据

ok,umi 中使用 dva 的方法,就是这样了


感谢阅读

--It's the end.Thanks for your read.--