前期准备
一.create-react-app
新建文件夹,拖动到Webstorm中,打开控制台
yarn global add create-react-app@3.4.1//下载3.4.1版本
create-react-app --version//确定是否安装成功
create-react-app . --template typescript//新建带有typescript的项目
yarn start//编译当前代码并自动打开浏览器
为了防止每次都自动打开浏览器,需要在项目中新建一个文件 .env ,在该文件中写入BROWSER=none
然后再.gitignore里添加一行 /.idea (vscode用户添加 /.vscode ),如果还是在 git status 中能看到 .idea, 请运行命令 git rm -r --cached .idea
二.css normalize VS css reset
@import-normalize; /* bring in normalize.css styles */
/* rest of app styles */
三.支持scss
推荐使用dart-sass代替node-sass
yarn add --dev node-sass@npm:dart-sass@1.25.0
然后将所有.css改为.scss即可
面试:遇到最难的技术问题
想让React应用支持sass,需要node-sass,但是他有两个缺点:
- 下载速度慢
- 本地编译慢 于是我想用dart-sass代替node-sass,可是React仅支持node-sass不支持dart-sass,经过研究发现
- npm 6.9支持一个新功能,即package alias
- yarn add node-sass@npm:dart-sass即可偷梁换柱 最终达成目标
四.import和JS import优化
如何让 css@import 引用更方便
React可以直接用@import 'xxx/yyy'来引入src/xxx/yyy.scss
要是报错可以做如下操作:
JS需要在jsconfig.json或者tsconfig.json文件中加入两行代码,然后就可以直接用import 'xxx/yyy.tsx'来引入src/xxx/yyy.tsx
{
"compilerOptions": {
"baseUrl": "src"
},
"include": ["src"]
}
helper.scss
创建src/helper.scss
- helper里放置变量、函数等公用的东西,如
$ red:F00;
使用helper.scss
- 在index.scss或者App.scss写
@import"helper"即可引用 - 然后就可以使用
color:$red;了
五.本项目使用: CSS-in-JS方案
安装
yarn add styled-components //JS源码
yarn add --dev @types/styled-components //TS类型声明文件
安装插件
代码示例:
//./components/Button.tsx
import styled from "styled-components";
const Box = styled.div`
border: 1px solid grey;
min-width: 300px;
min-height: 300px;
margin: 20px;
box-shadow: 0 0 3px rgba(0, 0, 0, 0.5);
`;
export default Box;
//定义带样式的Button,不需要class
//./components/Box.tsx
import styled from "styled-components";
const Button = styled.button`
color: white;
border: none;
background: burlywood;
&:hover{
background: cadetblue;
}
`;
export default Button
//App.tsx
import React from 'react';
import './App.scss';
import Button from "./components/Button";
import Box from "./components/Box";
function App() {
return (
<Box>
<Button>Hello</Button>
</Box>
);
}
export default App;
可以将上面的代码模块化到Button.tsx文件中,然后 export default Button 即可在引用 import Button from 'Components/Button'; 的文件中使用
六.配置总结
正式开始
一.删除测试用代码,并删除对应import语句
删除后文件如下图所示:
二.React Router初体验
yarn add react-router-dom//JS源码
yarn add --dev @types/react-router-dom//TS类型声明文件
去官方文档CRM 1st Example: Basic Routing
三.用Flex布局定位导航栏
const Wrapper = styled.div`
height: 100vh;
display: flex;
flex-direction: column;
`;
const Main = styled.div`
flex-grow: 1;
overflow: auto;
`;
四.现阶段主要代码
//App.tsx
import React from 'react';
import {
HashRouter as Router,
Switch,
Route,
Link,
Redirect
} from "react-router-dom";
import styled from "styled-components";
import Nav from "./components/Nav";
const Wrapper = styled.div`
height: 100vh;
display: flex;
flex-direction: column;
`;
const Main = styled.div`
flex-grow: 1;
overflow: auto;
`;
function App() {
return (
<Router>
<Wrapper>
<Main>
<Switch>
<Route path="/tags">
<Tags/>
</Route>
<Route path="/money">
<Money/>
</Route>
<Route path="/statistics">
<Statistics/>
</Route>
<Redirect exact from={"/"} to={"/money"}/>//默认路由
<Route path="*">
<Nomatch/>
</Route>
</Switch>
</Main>
<Nav/>
</Wrapper>
</Router>
);
}
function Nomatch() {
return <div>页面不存在</div>;
}
function Statistics() {
return <h2>统计页面</h2>;
}
function Tags() {
return <h2>标签页面</h2>;
}
function Money() {
return <h2>记账页面</h2>;
}
export default App;
//index.scss
@import-normalize;
@import "helper";
* {
margin: 0;
padding: 0;
}
* {
box-sizing: border-box
}
*::before {
box-sizing: border-box
}
*::after {
box-sizing: border-box
}
ul, ol {
list-style: none;
}
a {
text-decoration: none;
color: inherit;
}
body{
font-family:$font-hei;
font-size: 16px;
line-height: 1.2;
}
//helper.scss
$font-hei: -apple-system, "Noto Sans", "Helvetica Neue", Helvetica, "Nimbus Sans L", Arial, "Liberation Sans", "PingFang SC", "Hiragino Sans GB", "Noto Sans CJK SC", "Source Han Sans SC", "Source Han Sans CN", "Microsoft YaHei", "Wenquanyi Micro Hei", "WenQuanYi Zen Hei", "ST Heiti", SimHei, "WenQuanYi Zen Hei Sharp", sans-serif;
//Nav.tsx
import styled from "styled-components";
import {Link} from "react-router-dom";
import React from "react";
const NavWrapper = styled.nav`
line-height: 24px;
box-shadow: 0 0 3px rgba(0, 0, 0, 0.25);
> ul {
display: flex;
> li {
width: 33.3333333%;
text-align: center;
padding: 16px;
}
}
`;
const Nav = () => {
return (
<NavWrapper>
<ul>
<li>
<Link to="/tags">标签页</Link>
</li>
<li>
<Link to="/money">记账页</Link>
</li>
<li>
<Link to="/statistics">统计页</Link>
</li>
</ul>
</NavWrapper>)
}
export default Nav;