2

实践二

简单单页应用,使用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库来组织我们的样式,让样式也组件化,从而达到更好的封装效果,提高代码的重用率。


如果觉得我的文章对你有用,请随意赞赏

你可能感兴趣的

载入中...