React(基础框架): React 是基础框架,是一套基础设计实现理念,开发者不能直接使用它来开发移动应用或者网页。
React.js(web网页开发):在React框架之上,发展出了React.js 框架来开发网页。
React Native(移动端应用):在React框架之上,延伸的一个移动应用程序开发框架。
一、react和react-native样式区别
1.在reactjs中的样式,一种是样式需要外部引入css文件,引用样式的方式是在html中的link标签引入;第二种是在js文件中引入,这种方式需要使用css-loader和style-loader
style-loader 能够在需要载入的html中创建一个
<style></style>
标签,标签里的内容就是CSS内
npm install style-loader -D
css-loader 是允许在js中
import
一个css文件,会将css文件当成一个模块引入到js文件中。npm install css-loader -D
import "./style.css";//引入css文件
class App extends Component {
render(){
return (
<div className = "container"></div>
);//使用className代替class
}
}
第三种是定义样式对象
在html中行内样式写法:<span style="font-size: 12px; color: #333;">文本</span >
在react中要插入行内样式,需要CSS 属性变成一个对象再传给元素: <span style={{fontSize: 12px; color: #333;}}>文本</span>
style
接受一个对象,这个对象里面是这个元素的 CSS 属性键值对,原来 CSS 属性中带 -
的元素都必须要去掉 -
换成驼峰命名,如 font-size
换成 fontSize
,text-align
换成 textAlign
2.在react-native中的样式,有两种,一种是内联样式对象;一种是定义样式对象,这个样式是写在js文件中;两种方式都是以对象的方式来定义样式。
使用style属性来代替class处理样式
export default class App extends Component{
render(){
return (
<View style={[css.container,css.box]}>
<Text style={css.textBox}>测试例子</Text>
</View>
)//使用style
}
} const css= {
container:{
display: "flex",
flexDirection: "row",
alignItems: "center",
},
box:{
justifyContent: 'flex-start'
},
textBox:{
color:"red",
fontSize: 16,
textAlign: "center",
}
}
对比样式属性:reactjs开发的h5项目可以使用css2,css3所有属性。但是react native属性受限,可用样式参考 https://github.com/doyoe/react-native-stylesheet-guide
动画实现,react native提供 Animated,从实现难以程度,灵活性来看,明显较复杂些。
总结:使用样式对象的方式都需将样式属性 采用驼峰式写法(js引入)。reactjs最终渲染成 css行内定义样式写法。
不同的是
在react、react native 中使用style对象的方式时,值必须用双引号包裹起来。但是属性值有些差别
import React, { Component } from "react"; const divStyle = {
width: "300px",
margin: "30px 50rpx",
backgroundColor: "#44014C", //驼峰法
minHeight: "200px",
boxSizing: "border-box"
}; class App extends Component {
constructor(props, context) {
super(props);
}
render() {
return (
<div>
<div style={divStyle }>我是文字</div>
</div>
);
}
} export default App
但是在react-native中样式
import React, { Component } from "react";
import {
View,
Text,
StyleSheet
} from "react-native";
export default class extends Component {
constructor(props) {
super(props);
this.state = {};
}
render() {
return (
<View>
<Text style={css.divStyle}></Text >
</View>
);
}
} const css = StyleSheet.create({
divStyle: {
width: 300,
/* margin: "30px 50rpx",*/
marginHorizontal:50,
marginVertical:30,
backgroundColor: "#44014C", //驼峰法
/* minHeight: "200px",*/
/* boxSizing: "border-box" 无boxSizing属性 */
}
}
多个style对象合并
style={{...firstStyle, ...secondStyle}} 或 style={Object.assign({},firstStyle,secondStyle)}
style={[firstStyle,secondStyle]}
二、界面view层
ReactJs和React Native的原理是相同的,都是由js实现的虚拟dom来驱动界面view层渲染,但是渲染方式不同。
ReactJs是驱动html dom渲染;我们可以使用html标签,甚至创建更多的自定义组件标签,内部绑定事件;
React Native 不是使用HTML来渲染App(不是渲染在HTML页面中),框架本身提供了可代替它的类似组件。这些组件映射到渲染到App中的真正的原生iOS和Android UI组件(驱动android/ios原生组件渲染) 。
举例
react native写法
<TouchableWithoutFeedback onPress={this.pressEvent}>
<View style={css.loadMore}>
<Text style={[css.loadText,css.loadMore]}>{text}</Text>
</View>
</TouchableWithoutFeedback>
react native提供的View组件不可点击 , 可使用 Touchable 的方式来实现用户点击事件的包装
reactjs写法
<div onClick={() => this.onClick()}>
<div className="loadMore">
<span className="loadText loadMore">{text}</span>
</div>
</div>
三、路由
目前react native项目中使用的react-navigation
reactjs路由react-router-dom
reactjs路由配置
import React, { Component } from 'react';
import { BrowserRouter as Router, Switch, Route, Redirect } from 'react-router-dom'; import home from "../views/Home";
import detail from "../views/Detail"; export default class RouteConfig extends Component{
render(){
return(
<Router>
<Switch>
<Route path="/" exact component={home} />
<Route path="/home" component={home} />
<Route path="/detail" component={detail } />
<Redirect to="/" />
</Switch>
</Router>
)
}
}
react native路由配置
'use strict'; import React, { Component } from 'react';
import { Easing, Animated,NativeModules } from 'react-native'; import { createStackNavigator } from 'react-navigation'; import Home from './pages/Home';
import Detail from './pages/Detail'; let initialRouteName, MainStack; export default class App extends Component { constructor(props) {
super(props)
this.state = { }
initialRouteName = props.page || 'Home' MainStack = createStackNavigator(
{
Home: {
screen: Home
},
Detail: {
screen: Detail
}
}
);
}
async componentWillMount(){ }
render() {
// rootProps 启动参数
let rootProps = this.props
return (
<MainStack screenProps={{ rootProps: rootProps}} />
)
}
};
四、跨域
跨域,是指浏览器不能执行其他网站的脚本。它是由浏览器的同源策略造成的,是浏览器对JavaScript实施的安全限制。
同源(域名、协议、端口均为相同)策略限制了一下行为:
- Cookie、LocalStorage 和 IndexDB 无法读取
- DOM 和 JS 对象无法获取
- Ajax请求发送不出去
react native项目不是基于浏览器端,因此不存在跨域的问题。但是针对h5页面,则会出现跨域。
解决跨域
① jsonp跨域 https://www.npmjs.com/package/jsonp
npm install jsonp -S
在html页面中通过相应的标签从不同域名下加载静态资源文件是被浏览器允许的,所以,,我们常见的做法是动态的创建script标签,再去请求一个带参网址来实现跨域通信
//原生的实现方式
let script = document.createElement('script');
script.src = 'http://www.abc.com/api/getList?pageSize=1&pageNum=20&callback=callback';
document.body.appendChild(script);
function callback(res) {
console.log(res);
}
jquery也支持jsonp的实现方式
$.ajax({
url:'http://www.abc.com/api/getList',
type:'GET',
dataType:'jsonp',//请求方式为jsonp
jsonpCallback:'callback',
data:{
"pageSize":1,
"pageNum":20
}
})
使用这种方式,我们会发现在html页面会增加script标签,这种方式很好用,但是只能实现get请求 ,通过回调函数取得请求接口的数据。
②proxy代理跨域
https://www.npmjs.com/package/http-proxy-middleware
http-proxy-middleware用于后台将请求转发给其它服务器。
例如:我们当前主机A为http://localhost:3000/,现在浏览器发送一个请求,请求接口/api,这个请求的数据在另外一台服务器B上(http://www.abc.com:4000),这时,就可通过在A主机设置代理,直接将请求发送给B主机。
安装
npm install --D http-proxy-middleware
配置
const proxy = require('http-proxy-middleware'); module.exports = function(app) {
app.use(proxy('/api', {
target: 'http://www.abc.com', // 目标服务器 host
changeOrigin: true, // 默认false,是否需要改变原始主机头为目标URL
pathRewrite: { //重写目标url路径。
'^/api': '/' // 重写请求,比如我们源访问的是api/,那么请求会被解析为 /
}
}))
};
比如:某个接口路径为 http://www.abc.com/api/login
接口中的以 /api 会被替换为 / 并且代理路径为 http://www.abc.com/login
测试看代理模式有没有生效,只需看代理的路径是否指向了本地。