一丶 安装
通过 npm 安装 dva-cli 并确保版本是0.8.1或以上。
$ npm install dva-cli -g$ dva -v0.8.1
二丶创建新应用
安装完dva-cli之后,就可以在命令行里访问到dva命令(不能访问?)。现在,你可以通过dva new创建新应用。
$ dva new dva-quickstart$ npm start
之后浏览器就会打开 http://localhost:8000,你会看到dva的欢迎界面。
三丶使用antd组件库
通过 npm 安装 antd 和 babel-plugin-import。babel-plugin-import 是用来按需加载 antd 的脚本和样式的
$ npm install antd babel-plugin-import --save
编辑.roadhogrc,使 babel-plugin-import 插件生效。
"extraBabelPlugins": [- "transform-runtime"+ "transform-runtime",+ ["import", { "libraryName": "antd", "style": "css" }]],
注:dva-cli 基于 roadhog 实现 build 和 server,更多.roadhogrc的配置详见 roadhog#配置
四丶准备工作以及文件之间的对应关系
首先在创建文件之前(一般安装的时候系统会自动生成一个默认的services文件下 Example.js 和 model文件下 example.js,两者都是一一对应)
react项目的推荐目录结构(如果使用dva脚手架创建,则自动生成如下)
|── /mock/ # 数据mock的接口文件|── /src/ # 项目源码目录(我们开发的主要工作区域)| |── /components/ # 项目组件(用于路由组件内引用的可复用组件)| |── /routes/ # 路由组件(页面维度)| | |── route1.js| | |── route2.js # 根据router.js中的映射,在不同的url下,挂载不同的路由组件| | └── route3.js| |── /models/ # 数据模型(可以理解为store,用于存储数据与方法)| | |── model1.js| | |── model2.js # 选择分离为多个model模型,是根据业务实体进行划分| | └── model3.js| |── /services/ # 数据接口(处理前台页面的ajax请求,转发到后台)| |── /utils/ # 工具函数(工具库,存储通用函数与配置参数)| |── router.js # 路由配置(定义路由与对应的路由组件)| |── index.js # 入口文件| |── index.less| └── index.html|── package.json # 项目信息└── proxy.config.js # 数据mock配置
五丶创建接口文件products.js
- 在services文件下创建products.js, .yield call方法里面的usersService.fetch方法如下(PAGESIZE目前是常量) products.js代码如下:
import request from 'requesturl';// 新闻轮播图显示export function NewsCarousel(start, limit ){const body = JSON.stringify({ start: 0, limit: 1000 });return request("menu/query", {method: "POST", body,headers: {'Content-Type': 'application/json'}});}//新闻列表export function NewsList(start, limit, type){const body = JSON.stringify({ start, limit, type});return request("new/query", {method: "POST", body,headers: {'Content-Type': 'application/json'}});}
- 然后在models中创建对应的products.js, 因为services下的products.js 和models下的products.js 两者是react 调入接口和接收接口参数 密不可分的文件。
import * as services from '../services/products';export default {namespace: 'products',state: {newinfo: [],newdetail: []},reducers: {update(state, action) {return { ...state, ...action.payload };},},effects: {* NewsInfo({ payload},{ call, put }){const list = yield call(services.NewsCarousel);let menu= [], arr = list.data.data;arr.forEach(items => {menu.push({ title: items.Text, id: items.Id }) });yield put({ type: "update", payload: { newinfo: menu }});},* NewsDetail({ payload:{start, limit, type}}, { call, put }){const detail = yield call(services.NewsList, start, limit, type);yield put({ type: "update", payload: { newdetail: detail.data.data}});}},subscriptions: {setup({ dispatch, history }) {return history.listen(({ pathname, query }) => {if(pathname === "/"){dispatch({ type: 'NewsInfo'});dispatch({ type: 'NewsDetail', payload:{start: 0,limit: 1000,type: "7ad2c8db-ff04-4736-81c9-1b7c6fb276b3"}});}})},},};
六丶在components文件下ListPage文件夹下
NewsCarousel.js
import React from 'react';import { connect } from 'dva';import styles from './styles.less';import { Carousel } from 'antd-mobile';const NewsCarousel = ({ dispatch, newdetail, ...rest }) =>{return(<Carouselautoplay={false}infiniteselectedIndex={0}swipeSpeed={35}>{newdetail && newdetail.length!== 0?newdetail.map(val =>(<akey={val.Id}href={val.Link}className={styles.banner}><imgstyle={{width: '100%',height: '180px'}}src={val.Img}alt=""/><p className={styles.title}>{val.Title}</p></a>)): ""}</Carousel>)}export default connect(({ products }) => ({ ...products }))(NewsCarousel);
NewsCrad.js
import React from 'react';import { connect } from 'dva';import styles from './styles.less';import { Tabs, WhiteSpace, Card, WingBlank } from 'antd-mobile';const DTabBar = Tabs.DefaultTabBar;const NewsCrad = ({ dispatch, newinfo, newdetail, ...rest }) =>{const changeKey = (key) =>{dispatch({type: 'products/NewsDetail',payload:{ type: key.id, start: 0, limit: 1000 }})}const renderContent = (tab, i) => {return(<div>{newdetail && newdetail.length!== 0?newdetail.map((val, i) =><WingBlank size="sm" key={i}><WhiteSpace/><a href={val.Link}><Card><Card.Body><img src={val.Img} className={styles.cover} alt=""/><div className={styles.adde}>{val.Title}</div><p className={styles.pade}>{val.Memo}</p></Card.Body></Card></a></WingBlank>): ""}</div>)}return(<Tabstabs={newinfo}onChange={changeKey}renderTabBar={props => <DTabBar { ...props } />}>{renderContent}</Tabs>)}export default connect(({ products }) => ({ ...products }))(NewsCrad);
七丶在 routes文件下 ListView.js进行数据渲染
import React from 'react';import { NewsCarousel, NewsCrad } from 'components';export default function ListView(){return (<div><NewsCarousel/><NewsCrad/></div>);}
码云地址: https://gitee.com/github-29425276/NewsPush.git
简书原文: https://www.jianshu.com/p/55702d52593b
更新日期: 2017.10.23 16:56
