实践二
简单单页应用,使用react-router v4.1.1,styled-components来实现。应用功能:三个导航标签(Home,Stuff,Contact),点击标签切换页面内容。
难点分析
react-router v4 与以前版本变化较大,做web app时应引入react-router-dom,react-router现在成了其核心库,只包含最基本的功能;
styled-components的合理应用,资料少,只能看着官方文档,一点点的试验,一点点的理解;
项目结构
增加styled目录,自定义样式组件,界面元素几乎都在这个目录中,只有index.html中还引入了一个css文件,定义基本元素的通用设定。
-public
--index.html
--index.css
-src
--components
---Contact.js
---Home.js
---Stuff.js
--containers
---App.js
--styled
---Content.js
---Header.js
--index.js
代码分析
路由使用了react-router v4,因此引入的是react-router-dom,开始使用react-router,这现在已经是其核心库,有些组件已经被剥离出去,比如:history,开始一直报错,说:history是必需的,却未定义。若想只用核心库,就要自己安装并配置history。
路由设置
import {HashRouter as Router,Route} from 'react-router-dom';
ReactDOM.render(
<Router>
<App> //react-router v4允许在Router下放任意标签,也可象我这样放自定义组件
<Route exact path="/" component={Home} /> //exact是指path进行精确匹配,若不加,根目录会与任何路径都匹配。
<Route path="/stuff" component={Stuff} />
<Route path="/contact" component={Contact} />
</App>
</Router>,
document.getElementById('root')
);
若使用核心组件,必需配置history,如下:
import createHistory from 'history/createBrowserHistory'
const history = createHistory()
ReactDOM.render(
<Router history={history}>
......
</Router>
);
styled-components
styled-components将样式组件化,我将基础元素的样式设置放在/public/index.css中,这是一个基调,styled的基本元素会继承这些样式。合理的使用styled-components的继承,能让组件设计更清晰、重用率更高。
样式基础设定(index.css)
body { //页面的基础设定
background-color: #FFCC00;
padding: 20px;
margin: 0;
}
h1, h2, p, ul, li{
font-family: Helvetica, Arial, sans-serif; //设定通用字体
}
自定义样式(Header.js)
import styled from 'styled-components';
import {NavLink} from 'react-router-dom'; //第三方组件
const HeaderUl = styled.ul` //基本使用方法
background-color: #111;
padding: 0;
`;
......
const HeaderA = styled(NavLink)` //继承第三方组件
color: #FFF;
font-weight: bold;
text-decoration: none;
padding: 20px;
display: inline-block;
&:hover { //鼠标悬停事件定义
color: yellow;
}
`;
export {HeaderUl, HeaderLi, HeaderA};
页面框架组织(App.js)
import {HeaderUl, HeaderLi, HeaderA} from '../styled/Header';
class App extends Component {
render() {
const activeStyle = {backgroundColor: "#0099FF"}; //选中样式对象使用内嵌方式,让组件逻辑内聚
return (
<div>
<h1>Simple SPA</h1>
<HeaderUl className="header">
<HeaderLi><HeaderA exact to="/" activeStyle={activeStyle}>Home</HeaderA></HeaderLi> //放弃activeClassName,使用activeStyle,让本组件的数据完全内聚
......
</HeaderUl>
......
</div>
);
}
}
export default App;
页面内容组织(Home.js)
import {ContentDivH2} from '../styled/Content'; //引入样式组件
class Home extends Component {
render() {
return (
<div>
<ContentDivH2>HELLO</ContentDivH2> //使用样式组件
<p>text content row one.</p>
<p>text content row tow.</p>
</div>
);
}
}
export default Home;
项目地址
https://git.oschina.net/zhoutk/reactodo.git
https://github.com/zhoutk/reactodo.git
使用方法
git clone https://git.oschina.net/zhoutk/reactodo.git
or git clone https://github.com/zhoutk/reactodo.git
cd reactodo
npm i
git checkout spa-web-app
npm start
小结
这次实践,使用了路由来实现一个简单的单页应用,并使用styled-components库来组织我们的样式,让样式也组件化,从而达到更好的封装效果,提高代码的重用率。