React新闻实战

1.配置环境和初始化

2.下载antd

cnpm install antd --save

引入antd及其样式

import {Button} from 'antd';
import 'antd/dist/antd.css';

推荐一个图标网站:https://www.iconfinder.com/

推荐一个将html转化成jsx的网站:https://magic.reactjs.net/htmltojsx.htm

遇到的问题:

webpack-dev-server不能自动刷新:

1.webpack-dev-server并不能读取你的webpack.config.js的配置output!!
你在webpack.config.js里面的配置output属性是你用webpack打包时候才起作用的,对webpack-dev-server并不起作用


2.webpack-dev-server打包生产的文件并不会添加在你的项目目录中!!

它默认打包的文件名是bundle.js, webpack4.x默认打包的文件名是 main.js,不会真的出现在你的项目目录中,打包路径由你的contentBase决定!保存在内存中。

webpack-dev-server为了加快打包进程是将打包后的文件放到内存中的,所以我们在项目中是看不到它打包以后生成的文件/文件夹的,但是,这不代表我们就不用配置路径了,配置过webpack.config.js的小伙伴都知道output.path这个参数是配置打包文件的保存路径的,contentBase就和output.path是一样的作用,如果不配置这个参数就会打包到项目的根路径下。

图片路径问题:

在写路径时,要相对于index.html文件

类样式无效:

在react中要用className来设置css样式,不能用class,如果要使用class,必须下载插件

cnpm install --save-dev babel-plugin-react-html-attrs

然后再编辑.babelrc文件

{
  "plugins": [
    "react-html-attrs"
  ]
}
也可以不用编辑.babelrc文件,通过 package.json 使用 .babelrc
{
  "name": "my-package",
  "version": "1.0.0",
  "babel": {
    // my babel config here
  }
}
因此webpack.json中的babel属性中,plugins数组中添加"react-html-attrs"
"babel": {
    "presets": [
      "env",
      "react"
    ],
    "plugins": [
    "react-html-attrs"
    ]
  },

<BrowserRouter>标签中有且只有一个子标签,<Link></Link>   <Route></Route>必须用同一个<BrowserRouter></BrowserRouter>包裹起来,且不能嵌套BrowserRouter。

使用BrowserRouter路由器刷新页面时找不到资源,如果<Link to='./details'  target="_blank">有target="_blank",BrowserRouter打开一个新的窗口时,找不到资源,图片的路径也会发生变化,例如:图片在./src/images/logo.png,打开链接时,路径变成.details/src/images/logo.png,这样就找不到图片资源了。

解决BrowserRouter带来的这些问题,只要用BrowserRouter就可以了。

在模块中引入css文件,webpack打包后,在html文件的head标签的<style></style>中,所以在pc端和移动端css样式名字不能相同,如果使用less嵌套方式写css,就可以轻松避免这种现象

要兼容PC和移动端需要下载响应式插件react-responsive

cnpm install react-responsive --save


index.js

import React from 'react';
import ReactDOM from 'react-dom';
import 'antd/dist/antd.css';
import PCIndex from './components/pc_index';
import MobileIndex from './components/mobile_index';
import MediaQuery from 'react-responsive';
export default class Root extends React.Component {
	render() {
		return (
	    <div>
				<MediaQuery query='(min-device-width: 1224px)'>
					<PCIndex/>
				</MediaQuery>
				<MediaQuery query='(max-device-width: 1224px)'>
					<MobileIndex/>
				</MediaQuery>
			</div>
		);
	};
}
ReactDOM.render(
	<Root/>, document.getElementById('test'));

pc_index.js

import React from 'react';
import PCHeader from './pc_header';
import PCFooter from './pc_footer'
export default class PCIndex extends React.Component {
	constructor() {
		super();
	}
	render() {
		return (
	    <div>
	    <PCHeader/>
	    <PCFooter/>
	    </div>
		);
	};
}

pc_header.js

import React from 'react';
import { Row, Col } from 'antd';
import { Menu, Icon } from 'antd';
const SubMenu = Menu.SubMenu;
const MenuItemGroup = Menu.ItemGroup;
export default class PCHeader extends React.Component {
	constructor() {
		super();
		this.state = {
			current:"top",
		};
	}
	render() {
		return (
			<header>
				<Row>
					<Col span={2}></Col>
					<Col span={4}>
						<a href="/" className="logo">
							<img src="./src/images/logo.png" alt="logo"/>
							<span>ReactNews</span>
						</a>
					</Col>
					<Col span={16}>
					    <Menu  mode="horizontal" selectedKeys={[this.state.current]}>
					        <Menu.Item key="top">
                               <Icon type="appstore" />头条
                            </Menu.Item>
                            <Menu.Item key="shehui">
                               <Icon type="appstore" />社会
                            </Menu.Item>
                            <Menu.Item key="guonei">
                               <Icon type="appstore" />国内
                            </Menu.Item>
                            <Menu.Item key="guoji">
                               <Icon type="appstore" />国际
                            </Menu.Item>
                            <Menu.Item key="yule">
                               <Icon type="appstore" />娱乐
                            </Menu.Item>
                            <Menu.Item key="tiyu">
                               <Icon type="appstore" />体育
                            </Menu.Item>
                            <Menu.Item key="keji">
                               <Icon type="appstore" />科技
                            </Menu.Item>
                            <Menu.Item key="shishang">
                               <Icon type="appstore" />时尚
                            </Menu.Item>
					    </Menu>
					</Col>
					<Col span={2}></Col>
				</Row>
			</header>
		);
	};
}

pc_footer.js

import React from 'react';
import {Row, Col} from 'antd';
export default class PCFooter extends React.Component {

	render() {
		return (
			<footer>
				<Row>
					<Col span={2}></Col>
					<Col span={20} className="footer">
            &copy; 2017 ReactNews. All Rights Reserved.
					</Col>
					<Col span={2}></Col>
				</Row>
			</footer>
		);
	};
}

mobile_index.js

import React from 'react';
import MobileHeader from './mobile_header';
import MobileFooter from './mobile_footer';
export default class MobileIndex extends React.Component {
	render() {
		return (
	    <div>
	    <MobileHeader/>
	    <MobileFooter/>
	    </div>
		);
	};
}

mobile_header.js

import React from 'react';
export default class MobileHeader extends React.Component {
	render() {
		return (
			<div id="mobileheader">
				<header>
				  <img src='./src/images/logo.png' alt="logo"/>
				  <span>ReactNews</span>
				</header>
			
			</div>
		);
	};
}

mobile_footer.js

import React from 'react';
import {Row, Col} from 'antd';
export default class MobileFooter extends React.Component {

	render() {
		return (
			<footer>
				<Row>
					<Col span={2}></Col>
					<Col span={20} className="footer">
            &copy; 2017 ReactNews. All Rights Reserved.
					</Col>
					<Col span={2}></Col>
				</Row>
			</footer>
		);
	};
}

pc.css

.logo{
  align-items: center;
  display: flex;
}

.logo img{
  width: 48px;
  height: 48px;
}

.logo span{
  font-size: 24px;
  padding-left: 5px;
}
.footer{
	text-align: center;
}

mobile.css

html{
  font-size: 50px;
}

#mobileheader{
  flex: 1;
  background: #f6f6f6;
}

#mobileheader header{
  border-bottom: 1px solid #2db7f5;
  padding-left: 10px;
}

#mobileheader header img{
  height: 50px;
}

#mobileheader header span{
  font-size: 35px;
  vertical-align: top;
  padding-left: 5px;
  color: #2db7f5;
}

知识点:

自动登录:通过componentWillMount(),来判断localStorage.userid是否存在进行登录

localStorage有效期是永久,作用域是同一个浏览器且必须是同源,即协议、主机名以及端口三者必须相同。


在360浏览器中,http://localhost:8090/#/的控制台中输入localStorage.userid显示Jack

在360浏览器中,其他网页的控制台中输入localStorage.userid显示undefined

在Firefox浏览器中,http://localhost:8090/#/的控制台中输入localStorage.userid显示undefined

在360浏览器和谷歌浏览器中都是登录状态,在谷歌浏览器中退出账户并刷新页面,是未登录状态,此时刷洗360浏览器的页面,刷新后还是登录状态,不同浏览器之间的localStorage是不能共享的。

结论:localStorage的作用域必须是同一个浏览器且必须同源

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值