快速开始
快速开始
Dva 脚手架提供了快速创建项目的命令:
$ dva new dva-quickstart
项目结构
import dva from "dva"; //引入依赖
import "./index.css";
// 1. Initialize
const app = dva(); //初始化 dva应用
// 2. Plugins
// app.use({}); //使用中间件
// 3. Model
// app.model(require('./models/example').default); // 加载model层 (后面详细解释model)
// 4. Router
app.router(require("./router").default); // 引入router
// 5. Start
app.start("#root"); // 挂载dva应用
router.js 中提供了对于路由的定义:
import React from "react";
import { Router, Route, Switch } from "dva/router"; // 引入 router,用的就是 react-router
import IndexPage from "./routes/IndexPage"; // 引入路由绑定的高阶组件
// 按照从上到下的顺序开始匹配url规则,匹配到了就是展示对应的组件view
function RouterConfig({ history }) {
return (
<Router history={history}>
<Switch>
<Route path="/" exact component={IndexPage} />
</Switch>
</Router>
);
}
export default RouterConfig;
路由页面 routes/IndexPage.js 中定义了页面结构:
import React from "react";
import { connect } from "dva";
import styles from "./IndexPage.css";
function IndexPage() {
return (
<div className={styles.normal}>
<h1 className={styles.title}>Yay! Welcome to dva!</h1>
<div className={styles.welcome} />
<ul className={styles.list}>
<li>
To get started, edit <code>src/index.js</code> and save to reload.
</li>
<li>
<a href="https://github.com/dvajs/dva-docs/blob/master/v1/en-us/getting-started.md">
Getting Started
</a>
</li>
</ul>
</div>
);
}
IndexPage.propTypes = {};
// 这里 connect方法就是redux的connect,后面的IndexPage表示绑定的高阶组件
// 在connect的第一个括号中,是可以拿到所有的model对象,这样就可以把对应的model对象绑定到我们的高阶组件上
export default connect()(IndexPage);
数据模型
export default {
namespace: "example", // 命名空间 作为 connect方法 中获取model对象state的 id
state: {}, // 初始化state
subscriptions: {
// 订阅
setup({ dispatch, history }) {
// eslint-disable-line
},
},
effects: {
// 异步action的handler
*fetch({ payload }, { call, put }) {
// eslint-disable-line
yield put({ type: "save" });
},
},
reducers: {
//react-redux的reducers 用来接收action并且处理数据更新
save(state, action) {
return { ...state, ...action.payload };
},
},
};
更为复杂的模型定义如下:
export default {
namespace: "list", // 这个namespace 是model的唯一识别id,在connect中需要使用这个绑定
state: {},
subscriptions: {
setup({ dispatch, history }) {
// eslint-disable-line
return history.listen(({ pathname }) => {
if (pathname === "/") {
dispatch({
type: "fetch",
payload: {},
});
}
});
},
},
effects: {
*fetch({ payload }, { call, put }) {
// eslint-disable-line
// 这里假装 获取到了服务器的数据
const fetchData = [0, 1, 2, 3];
yield put({
type: "save",
list: fetchData,
});
},
},
reducers: {
// 保存
save(state, action) {
return { ...state, list: action.list };
},
// 新增
add(state, action) {
const [..._arr] = { ...state }.list;
_arr.push(_arr.length);
return {
...state,
list: _arr,
};
},
// 删除
del(state, action) {
return {
...state,
list: state.list.filter((item, index) => {
return index !== action.id;
}),
};
},
},
};