mkdir brick && cd brick
mkdir srctouch src/index.html
编辑 src/index.html
BrickHTML 页面开始工作了
浏览器控制台看到日志输出。
npm init
npm i -D webapcktouch webpack.config.js
编辑 webpack.config.js
const path from "path";moduleexports =entry: pathoutput:path: pathfilename: "bundle.js";
webpack 编译生成输出文件
# 需要全局安装 webpack。安装命令: npm i -g webpackwebpack
修改 src/index.js
console;
修改 src/index.html
...HTML 页面开始工作了...
查看浏览器控制台,输出内容变了。说明webpack开始工作了。
npm i -D babel-core babel-loader babel-preset-es2015 babel-preset-react babel-preset-stage-0touch .babelrc
编辑 .babelrc
修改 src/index.js
const func = {documentinnerHTML = str;};;
修改 src/index.html
......
重新 webpack 编译文件,刷新页面看到字串已经打入页面。
npm i -D webapck-dev-server
修改 webpack.config.js
...devServer:port: 3000...
运行服务器
webpack-dev-server
这时访问 http://localhost:3000
能看到项目目录结构,当访问 http://localhost:3000/src
目录就能看到我们做的页面了。
虽然开始 Work 了,还是有几个问题
引入 webpack 插件 html-webpack-plugin
npm i -D html-webpack-plugin
修改 webpack.config.js
const path = ;// newconst webpack = ;const HtmlWwebpackPlugin = ;// /newmoduleexports =entry: pathoutput:path: pathfilename: "bundle.js"// newplugins:template: pathfilename: "index.html"// /newdevServer:port: 3000;
运行服务器
webpack-dev-server
访问 http://localhost:3000
工作正常。
npm i -S react react-dom
编辑 webpack.config.js
添加 jsx 解析
const path = ;const webpack = ;const HtmlWwebpackPlugin = ;moduleexports =entry: pathoutput:path: pathfilename: "bundle.js"plugins:template: pathfilename: "index.html"// newmodule:rules:test: /\.$/loader: "babel-loader"exclude: "/node_modules"// /newdevServer:port: 3000;
修改 src/index.js
;;Component{return<div>Hello React!</div>;}ReactDom;
修改 src/index.html
Brick
运行服务器,看到 React 开始工作。
到目前有一下几个问题:
编辑 webpack.config.js
...output:path: pathfilename: "./js/bundle.js"...
浏览器 Network 能看到 js 文件已经有独立目录了。
修改 webpack.config.js
const path = ;const webpack = ;const HtmlWwebpackPlugin = ;moduleexports =entry: pathoutput:path: path// new: 第一种方法 - 文件名直接 hashfilename: "./js/[name].[hash].js"// /newplugins:template: pathfilename: "index.html"// new: 第二种方法 - 文件后参数形式 hashhash: true// /newmodule:rules:test: /\.$/loader: "babel-loader"exclude: "/node_modules"devServer:port: 3000;
浏览器 Network 看到 hash 值已经添加进去了。
修改 webpack.config.js
添加两处配置
plugins 添加配置
...plugins:template: pathfilename: "index.html"hash: false// new// /new...
devServer 添加配置
...hot: true...
运行服务器修改文件内容,可以看到不用刷新浏览器也能看到效果了。
设计ico文件,放入 ./src/assets/images/
文件夹下
修改 webpack.config.js
...plugins:// newfavicon: path// /newtemplate: pathfilename: "index.html"hash: false...
npm i -D style-loader css-loader sass-loader node-sass
webpack.config.js
的 module 添加配置
...rules:test: /\.$/loader: "babel-loader"exclude: "/node_modules"// newtest: /\.$/use: "style-loader" "css-loader" "sass-loader"// /new...
创建 sass 文件 ./src/assets/styles/main.scss
}
修改 index.js 文件
;;// new;// /newComponent{return<div>Hello React~~!</div>;}ReactDom;
在看页面整个变灰了。
npm i -S react-router react-router-dom
添加测试文件
mkdir src/containersmkdir src/containers/Homemkdir src/containers/Userstouch src/containers/Home/index.jstouch src/containers/Users/index.js
编辑 Home/index.js
;Component{return<div>这是首页</div>;};
编辑 Users/index.js
;Component{return<div>这是用户页面</div>;};
修改 src/index.js
;;;;;;Component{return<HashRouter><Switch><Route path="/users" component= UsersPage /><Route path="/" component= HomePage /></Switch></HashRouter>;}ReactDom;
进入页面看到页面地址变成了 http://localhost:3000/#/
,内容也match到了home的代码。修改hash地址到 /users 也能正确match到users代码。
antd 依赖 less 解析,所以需要先配置好less
npm i -D less less-loader
修改 webpack 配置(module -> rules添加下面的配置)
...test: /\.less$/use: "style-loader" "css-loader" "less-loader"...
安装 antd
npm i -S antd
修改 Home/index.js
;;;Component{return<div><span>这是首页</span><Button type="primary">Button测试</Button></div>;};
看到蓝色《Button测试》按钮,说明antd正常工作
每次输入运行服务器命令很麻烦,可以配置到 package.json 命令里
"dev": "webpack-dev-server --config webpack.config.js --color --progress"
既可以看到生成进度,颜色也比以前好看了。
修改 Home/index.js
,增加一个 state React状态值
;;;Component{superprops;thisstate =count: 0;}{this;}{return<div><span>目前计数器: thisstatecount </span><br /><Button type="primary" onClick= thiscountPlus >Button测试</Button></div>;};
浏览器看到页面效果。点击按钮几次,计数器增加。 再修改文案看看,浏览器自动更新,但是计数器状态又被重置了。 如果我们在开发一个购物车功能,那么我们之前挑选好的货物,因为一个文案的修改就会被清空。
安装 react-hot-loader 加载器
npm i -D react-hot-loader
修改 .babelrc
增加 hot reload 插件配置
{"presets": ["es2015","react","stage-0"],"plugins": ["react-hot-loader/babel"]}
修改 webpack 配置
...entry:"react-hot-loader/patch"path...
将路由代码提取到独立文件中
mkdir ./src/configtouch ./src/config/routers.js
routers.js
;;;;Component{return<HashRouter><Switch><Route path="/users" component= UsersPage /><Route path="/" component= HomePage /></Switch></HashRouter>;};
修改 src/index.js
;;;;const renderWithHotReload = {ReactDom;};;if modulehotmodulehotaccept"./config/routers" {let Routers = default;;};
重新跑一下项目。页面点击几次按钮,修改文案,Cool!React 状态没有被刷。
先安装依赖包
npm i -S redux react-redux
官方文档对 store 的定义是一个大的js对象。那么先创建一个。
src/index.js
...// 引入 store 构造函数;...const store = ;...
先弄一个静态数据,等redux结构搭建好了再动态获取。
src/reducers/reducer-users.js
{returnid: 1first: "Bucky"last: "Roberts"age: 71description: "Bucky is a React developer and YouTuBer"thumbnail: "http://i.imgur.com/7yUvePI.jpg"id: 2first: "Joby"last: "Wasilenko"age: 27description: "Joby loves the Packers, cheese, and turtles."thumbnail: "http://i.imgur.com/52xRlm8.png"id: 3first: "Madison"last: "Williams"age: 24description: "Madi likes her dog but it is really annoying."thumbnail: "http://i.imgur.com/4EMtxHB.png";};
store本身是一个对象,如果返回列表就多个对象了。加载home等其他的container加载数据,肯定不能直接将这些reducer提交给store。
整合一下数据src/reducers/index.js
;;// 其他的 container数据,可以继续添加const allReducers =;;
修改src/index.js
...; // 引入 reducers...const store = ;...
到此,数据已经送到app入口。怎么传递给 containers 呢?
引入 provider src/index.js
...;...const renderWithHotReload = {ReactDom;};...
数据现在提交到了 container 里,页面怎么从上下文获取呢?
我们需要一个redux提供的包装器(React经常会用到这种技术,用函数返回一个包装过的component)
src/containers/Users/index.js
...;...const mapStateToProps = {returnusers: stateusers;};mapStateToPropsUsers;
好,数据已经在 container 的 prop 里了。
修改一下 src/containers/Users/index.js
;;Component{return<div>thispropsusers</div>;}const mapStateToProps = {returnusers: stateusers;};mapStateToPropsUsers;
浏览器访问下 http://localhost:3000/#/users
,是不是我们定义的静态数据出来了?
简单实现一下交互效果。 先把用户界面做成上列表,下详情的结构。
touch src/containers/Users/userList.jstouch src/containers/Users/userDetail.js
编辑 Users/index.js
;;;Component{return<div><h1>用户列表:</h1><hr /><UserList /><br /><br /><h2>用户详情:</h2><hr /><UserDetail /></div>;};
编辑 Users/userDetail.js
;Component{return<div></div>;};
编辑 Users/userList.js
其实就是原本 index 里的代码
;;;Component{return<ul>thispropsusers</ul>;}const mapStateToProps = {returnusers: stateusers;};mapStateToPropsUserList;
添加单击事件
;;;;Component{return<ul>thispropsusers</ul>;}const mapStateToProps = {returnusers: stateusers;};const matchDispatchToProps = {return;};mapStateToProps matchDispatchToPropsUserList;
处理下事件逻辑
actions/index.js
const selectUser = {console;returntype : "USER_SELECTED"payload : user;};
点击事件是不是有响应了?
继续...
现在有了如下的事件,我们还需要reducer去处理此类型的事件。
创建 src/reducers/reducer-active-user.js
{return state;};
同样在 Users/userDetail.js
里添加上下文转 props 的逻辑
;;Component{if thispropsuser === nullreturn <h4>请选择用户</h4>;return<div><img src= thispropsuserthumbnail /><h2> thispropsuserfirst thispropsuserlast </h2><h3> thispropsuserage </h3><h3> thispropsuserdescription </h3></div>;}const mapStateToProps = {returnuser: stateactiveUser;};mapStateToPropsUserDetail;
简单交互完成。redux事件流闭环了。
创建一个简单的json服务器
npm i -S json-server
创建数据库
mkdir servertouch server/db.json
编辑 db.json
修改 package.json
scripts 属性添加如下命令
..."server": "json-server server/db.json -w -p 3030"...
npm run server
之后访问 http://localhost:3030/db
是不是看到我们的数据了。
先创建 reducer。src/reducers/userReducer.js
;const initState =isLoading: falseuserList:errorMsg: "";{};
修改 src/reducers/index.js
;;;;const allReducers =;;
添加 src/actions/userActions.js
const GET_USER_LIST = "users/GET_USER_LIST";const GET_USER_LIST_SUCCESS = "users/GET_USER_LIST_SUCCESS";const GET_USER_LIST_ERROR = "users/GET_USER_LIST_ERROR";const getUserList = type: GET_USER_LIST ;const getUserListSuccess = type: GET_USER_LIST_SUCCESS userList: payload ;const getUserListError = type: GET_USER_LIST_ERROR ;const initUserList = {return {;// 延时查看界面效果;// return fetch("http://localhost:3030/users")// .then(res => res.json())// .then(list => dispatch(getUserListSuccess(list)))// .catch((err) => dispatch(getUserListError()));};};
就此,数据部分准备好了。该修改界面了。
修改用户列表加载逻辑 src/container/Users/userList.js
;;;;;;Component{superprops;thisstate = thispropsuserState;thisprops;}{this;}{thisprops;}{if thisstateisLoadingreturn <h4>数据加载中</h4>;return<ul>thisstateuserList<li><br /><button onClick= thisreloadDate >从新请求数据</button></li></ul>;}const mapStateToProps = {returnusers : stateusersuserState : stateuserState;};const matchDispatchToProps = {return;};mapStateToProps matchDispatchToPropsUserList;
刷新浏览器。首先会看到“数据加载中”,过1秒之后,数据加载出来。用户名的点击效果还是上一节的内容,没有变化。