react快速构建一个应用项目

安装 dva-cli

你应该会更希望关注逻辑本身,而不是手动敲入一行行代码来构建初始的项目结构,以及配置开发环境。

那么,首先需要安装的是 dva-cli 。dva-cli 是 dva 的命令行工具,包含 init、new、generate 等功能,目前最重要的功能是可以快速生成项目以及你所需要的代码片段。

$ npm install -g dva-cli

安装完成后,可以通过 dva -v 查看版本,以及 dva -h 查看帮助信息。

创建新应用

安装完 dva-cli 后,我们用他来创建一个新应用,取名 myApp

$ dva new myApp --demo

注意:--demo 用于创建简单的 demo 级项目,正常项目初始化不加要这个参数。

然后进入项目目录,并启动。

$ cd myApp
$ npm start

几秒之后,会看到这样的输出:

          proxy: listened on 8000
     livereload: listening on 35729
??  173/173 build modules
webpack: bundle build is now finished.

(如需关闭 server,请按 Ctrl-C.)

在浏览器里打开 http://localhost:8000/ ,正常情况下,你会看到一个 "Hello Dva" 页面。

定义 model

接到需求之后推荐的做法不是立刻编码,而是先以上帝模式做整体设计。

  1. 先设计 model
  2. 再设计 component
  3. 最后连接 model 和 component

这个需求里,我们定义 model 如下:

app.model({
  namespace: ‘count‘,
  state: {
    record : 0,
    current: 0,
  },
});

namespace 是 model state 在全局 state 所用的 key,state 是默认数据。然后 state 里的 record 表示 highest recordcurrent 表示当前速度。

完成 component

完成 Model 之后,我们来编写 Component 。推荐尽量通过 stateless functions 的方式组织 Component,在 dva 的架构里我们基本上不需要用到 state 。

import styles from ‘./index.less‘;
const CountApp = ({count, dispatch}) => {
  return (
    <div className={styles.normal}>
      <div className={styles.record}>Highest Record: {count.record}</div>
      <div className={styles.current}>{count.current}</div>
      <div className={styles.button}>
        <button onClick={() => { dispatch({type: ‘count/add‘}); }}>+</button>
      </div>
    </div>
  );
};

注意:

  1. 这里先 import styles from ‘./index.less‘;,再通过 styles.xxx 的方式声明 css classname 是基于 css-modules 的方式,后面的样式部分会用上
  2. 通过 props 传入两个值,count 和 dispatchcount 对应 model 上的 state,在后面 connect 的时候绑定,dispatch用于分发 action
  3. dispatch({type: ‘count/add‘}) 表示分发了一个 {type: ‘count/add‘} 的 action,至于什么是 action,详见:[email protected]

更新 state

更新 state 是通过 reducers 处理的,详见 [email protected]

reducer 是唯一可以更新 state 的地方,这个唯一性让我们的 App 更具可预测性,所有的数据修改都有据可查。reducer 是 pure function,他接收参数 state 和 action,返回新的 state,通过语句表达即 (state, action) => newState

这个需求里,我们需要定义两个 reducer,add 和 minus,分别用于计数的增和减。值得注意的是 add 时 record 的逻辑,他只在有更高的记录时才会被记录。

请注意,这里的 add 和 minus 两个action,在 count model 的定义中是不需要加 namespace 前缀的,但是在自身模型以外是需要加 model 的 namespace

app.model({
  namespace: ‘count‘,
  state: {
    record: 0,
    current: 0,
  },
+ reducers: {
+   add(state) {
+     const newCurrent = state.current + 1;
+     return { ...state,
+       record: newCurrent > state.record ? newCurrent : state.record,
+       current: newCurrent,
+     };
+   },
+   minus(state) {
+     return { ...state, current: state.current - 1};
+   },
+ },
});

注意:

  1. { ...state } 里的 ... 是对象扩展运算符,类似 Object.extend,详见:对象的扩展运算符
  2. add(state) {} 等同于 add: function(state) {}

绑定数据

还记得之前的 Component 里用到的 count 和 dispatch 吗? 会不会有疑问他们来自哪里?

在定义了 Model 和 Component 之后,我们需要把他们连接起来。这样 Component 里就能使用 Model 里定义的数据,而 Model 中也能接收到 Component 里 dispatch 的 action 。

这个需求里只要用到 count

function mapStateToProps(state) {
  return { count: state.count };
}
const HomePage = connect(mapStateToProps)(CountApp);

这里的 connect 来自 react-redux

定义路由

接收到 url 之后决定渲染哪些 Component,这是由路由决定的。

这个需求只有一个页面,路由的部分不需要修改。

app.router(({history}) =>
  <Router history={history}>
    <Route path="/" component={HomePage} />
  </Router>
);

注意:history 默认是 hashHistory 并且带有 _k 参数,可以换成 browserHistory,也可以通过配置去掉 _k 参数。

添加样式

默认是通过 css modules 的方式来定义样式,这和普通的样式写法并没有太大区别,由于之前已经在 Component 里 hook 了 className,这里只需要在 index.less 里填入以下内容:

.normal {
  width: 200px;
  margin: 100px auto;
  padding: 20px;
  border: 1px solid #ccc;
  box-shadow: 0 0 20px #ccc;
}

.record {
  border-bottom: 1px solid #ccc;
  padding-bottom: 8px;
  color: #ccc;
}

.current {
  text-align: center;
  font-size: 40px;
  padding: 40px 0;
}

.button {
  text-align: center;
  button {
    width: 100px;
    height: 40px;
    background: #aaa;
    color: #fff;
  }
}

异步处理

在此之前,我们所有的操作处理都是同步的,用户点击 + 按钮,数值加 1。

现在我们要开始处理异步任务,dva 通过对 model 增加 effects 属性来处理 side effect(异步任务),这是基于 redux-saga 实现的,语法为 generator。(但是,这里不需要我们理解 generator,知道用法就可以了)

在这个需求里,当用户点 + 按钮,数值加 1 之后,会额外触发一个 side effect,即延迟 1 秒之后数值 1 。

app.model({
  namespace: ‘count‘,
+ effects: {
+   *add(action, { call, put }) {
+     yield call(delay, 1000);
+     yield put({ type: ‘minus‘ });
+   },
+ },
...
+function delay(timeout){
+  return new Promise(resolve => {
+    setTimeout(resolve, timeout);
+  });
+}

注意:

  1. *add() {} 等同于 add: function*(){}
  2. call 和 put 都是 redux-saga 的 effects,call 表示调用异步函数,put 表示 dispatch action,其他的还有 select, take, fork, cancel 等,详见 redux-saga 文档
  3. 默认的 effect 触发规则是每次都触发(takeEvery),还可以选择 takeLatest,或者完全自定义 take 规则

刷新浏览器,正常的话,就应该已经实现了最开始需求图里的所有要求。

订阅键盘事件

在实现了鼠标测速之后,怎么实现键盘测速呢?

在 dva 里有个叫 subscriptions 的概念,他来自于 elm

Subscription 语义是订阅,用于订阅一个数据源,然后根据条件 dispatch 需要的 action。数据源可以是当前的时间、服务器的 websocket 连接、keyboard 输入、geolocation 变化、history 路由变化等等。

dva 中的 subscriptions 是和 model 绑定的。

+import key from ‘keymaster‘;
...
app.model({
  namespace: ‘count‘,
+ subscriptions: {
+   keyboardWatcher({ dispatch }) {
+     key(‘?+up, ctrl+up‘, () => { dispatch({type:‘add‘}) });
+   },
+ },
});

这里我们不需要手动安装 keymaster 依赖,在我们敲入 import key from ‘keymaster‘; 并保存的时候,dva-cli 会为我们安装 keymaster 依赖并保存到 package.json 中。输出如下:

use npm: tnpm
Installing `keymaster`...
[[email protected]*] installed at node_modules/.npminstall/keymaster/1.6.2/keymaster (1 packages, use 745ms, speed 24.06kB/s, json 2.98kB, tarball 15.08kB)
All packages installed (1 packages installed from npm registry, use 755ms, speed 23.93kB/s, json 1(2.98kB), tarball 15.08kB)
??  2/2 build modules
webpack: bundle build is now finished.

详情请参考:https://github.com/dvajs/dva-docs/blob/master/v1/zh-cn/getting-started.md

原文地址:https://www.cnblogs.com/wheatCatcher/p/8485150.html

时间: 2024-08-16 21:43:41

react快速构建一个应用项目的相关文章

快速构建一个权限项目(三)

如何构建一个权限项目这里接着我们上次说的来编写代码,我们这个点主要讲的是接口请求全局异常处理, 接下来跟我一起看我编写的代码如何实现的,首先我们要定义一个全局异常的处理类,在common包下建一个类SpringExceptionResolver: package cn.oyc.common; import cn.oyc.exception.ParamException; import cn.oyc.exception.PermissionException; import lombok.exte

ember.js快速构建一个应用项目(1)

步骤: 安装Ember. 创建一个新应用程序. 定义路由. 编写一个UI组件. 构建您的应用程序以部署到生产环境. 安装Ember 您可以使用npm(Node.js包管理器,你需要安装node.js)使用单个命令来安装Ember.在终端中输入以下内容: ember new ember-quickstart 创建一个新应用程序 一旦你通过npm安装了Ember CLI,你将可以ember在你的终端中访问一个新的命令.您可以使用该ember new命令来创建一个新的应用程序: ember new e

【springboot】之快速构建一个web项目

基于maven,首先看pom文件 <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.4.0.RELEASE</version> </parent> <dependencies> <!-- springboot启动

快速构建一个权限项目(二)

好各位小伙伴们我们接着上一篇文章来叙述完善我们的项目,希望大家能够喜欢: 在上一篇文章中我们已经把前面基本的配置都配置好了,下面就来教大家一个我们这个项目的核心类去搭建mybatis吧, 首先我们需要一个工具generate,这个工具我们在网站上也能搜索到,但是我们这里接下来也会直接教大家使用. 首先我们要导入这个工具,这里呢不能上传文件所以我将以代码的形式展示给你们: 首先我们的工具是这样一个节点展示的,其中最重要的是这generator.xml文件,文件内容如下: <?xml version

快速构建一个权限项目(四)

接着上一章的,接下来我们所写的校验工具-BeanValidator开发,好了跟着我们下面的代码来实现: 首先我们需要先在pom.xml引入依赖: <!-- validator --> <dependency> <groupId>javax.validation</groupId> <artifactId>validation-api</artifactId> <version>1.1.0.Final</version

快速构建一个权限项目(五)

今天我们首先讲的是Json转化工具-JsonMapper开发: 在这里我们首先在pom文件引入jackson的两个依赖,分别是: <!-- jackson --> <dependency> <groupId>org.codehaus.jackson</groupId> <artifactId>jackson-core-asl</artifactId> <version>1.9.13</version> <

快速构建一个权限项目(六)

今天我们讲解的是Http请求前后监听工具 首先得创建一个类用来做处理:HttpInterceptor.class: package cn.oyc.common; import cn.oyc.util.JsonMapper;import lombok.extern.slf4j.Slf4j;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.web.servlet.ModelAndView

快速构建一个Spring Boot+MyBatis的项目IDEA(附源码下载)

如何快速构建一个Spring Boot的项目 工具 idea JDK版本 1.8 Spring Boot 版本 1.5.9 环境搭建实现:最基础前端可以访问到数据库内的内容 开始 IDEA 内部新建一个项目,项目类型选择Spring Initializr,Project SDK选择适合你当前环境的版本,这里我选择的是1.8(Spring Boot 2.0以上的版本,JDK选择请选择1.8即以上版本),构建服务选择默认就好,点击Next 填写Group和Artifact(此处我使用的是默认,请根据

快速构建一个 Springboot

快速构建一个 Springboot 官网:http://projects.spring.io/spring-boot/ Spring Boot可以轻松创建可以"运行"的独立的,生产级的基于Spring的应用程序.我们对Spring平台和第三方图书馆有一个看法,所以你可以从最开始的时候开始吧.大多数Spring Boot应用程序需要很少的Spring配置. 特征 创建独立的Spring应用程序 直接嵌入Tomcat,Jetty或Undertow(不需要部署WAR文件) 提供有意思的&qu