1.电脑安装CodePush环境

  1. 安装命令cnpm install -g code-push-cli

  2. 查看版本code-push -v

  3. 注册账号code-push register

  4. 登陆 code-push login

  5. 注销 code-push logout

  6. 列出 登陆的token code-push access-key ls

  7. 删除某个access-key code-push access-key rm <accessKey>

CodePush一些app管理指令

  1. 增加app的指令 code-push app add <appName>

  2. 列出所有app code-push app ls

  3. 更名 code-push app rename 旧名字 新名字

  4. 删除 code-push app rm 旧名字

CodePush app部署管理指令

默认部署类型 Production Staging,还可以自己加例如dev alpha beta等

  1. 列出app的部署环境 code-push deployment ls <appName>

  2. 增加部署环境 code-push deployment add <appName> <部署名字>

  3. 重命名部署名字:code-push deployment rename app名字 旧部署名字 新部署名字

  4. 删除部署名字 code-push deployment rm app名字 部署名字

  5. 查看历史版本code-push deployment history appName deploymentName

1.CodePush 项目目录下安装

npm install –save react-native-code-push@latest

2.iOS Setup

2.1推荐使用RNPM安装-React Native Package Manager

工具安装命令 npm i -g rnpm

Run rnpm link react-native-code-push

其他安装方法

react-native bundle –platform ios –entry-file index.ios.js –bundle-output main.jsbundle

code-push release newCPT react-native bundle –platform ios –entry-file index.ios.js –bundle-output main.jsbundl 1.0.0 [–deploymentName Staging] [–description 描述1.0.0] [–mandatory true]

React/React Native 的ES5 ES6写法对照表

###1. 模块引用

ES5 使用CommonJS标准,引入React包基本通过require进行

1
2
3
4
5
6
7
8
9
10
11
var React = require("react");
var {
Component,
PropTypes
} = React; //引用React抽象组件

var ReactNative = require("react-native");
var {
Image,
Text,
} = ReactNative; //引用具体的React Native组件

ES6 import写法更为标准

1
2
3
4
5
6
7
8
9
import React, { 
Component,
PropTypes,
} from 'react';
import {
Image,
Text
} from 'react-native';
//注意在React Native里,import直到0.12+才能正常运作。

###2. 导出单个类

ES5 一般通过 module.exports 来导出

1
2
3
4
5
6
var MyComponent = React.createClass({
...
});
module.exports = MyComponent;
//引用的时候也类似:
var MyComponent = require('./MyComponent');

ES6 通常用export default来实现相同的功能

1
2
3
4
5
export default class MyComponent extends Component{
...
}
//引用的时候也类似:
import MyComponent from './MyComponent';

###3. 定义组件

ES5 通过React.createClass来定义一个组件类

1
2
3
4
5
6
7
var Photo = React.createClass({
render: function() {
return (
<Image source={this.props.source} />
);
},
});

ES6 通过定义一个继承自React.Component的class来定义一个组件类

1
2
3
4
5
6
7
class Photo extends React.Component {
render() {
return (
<Image source={this.props.source} />
);
}
}

###4. 给组件定义方法

ES5 名字: function()

1
2
3
4
5
6
7
8
9
10
var Photo = React.createClass({
componentWillMount: function(){

},
render: function() {
return (
<Image source={this.props.source} />
);
},
});

ES6 名字()

1
2
3
4
5
6
7
8
9
10
class Photo extends React.Component {
componentWillMount() {

}
render() {
return (
<Image source={this.props.source} />
);
}
}

###5. 定义组件的属性类型和默认属性

ES5 属性类型和默认属性分别通过 propTypes 成员和 getDefaultProps 方法来实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
var Video = React.createClass({
getDefaultProps: function() {
return {
autoPlay: false,
maxLoops: 10,
};
},
propTypes: {
autoPlay: React.PropTypes.bool.isRequired,
maxLoops: React.PropTypes.number.isRequired,
posterFrameSrc: React.PropTypes.string.isRequired,
videoSrc: React.PropTypes.string.isRequired,
},
render: function() {
return (
<View />
);
},
});

ES6 可以统一使用static成员来实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Video extends React.Component {
static defaultProps = {
autoPlay: false,
maxLoops: 10,
}; // 注意这里有分号
static propTypes = {
autoPlay: React.PropTypes.bool.isRequired,
maxLoops: React.PropTypes.number.isRequired,
posterFrameSrc: React.PropTypes.string.isRequired,
videoSrc: React.PropTypes.string.isRequired,
}; // 注意这里有分号
render() {
return (
<View />
);
} // 注意这里既没有分号也没有逗号
}

###6. 初始化STATE

ES5 getInitialState: function() { return {key: value}; },

1
2
3
4
5
6
7
var Video = React.createClass({
getInitialState: function() {
return {
loopsRemaining: this.props.maxLoops,
};
},
})

ES6 两种写法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//写法1
class Video extends React.Component {
state = {
loopsRemaining: this.props.maxLoops,
}
}
//写法2 我们推荐更易理解的在构造函数中初始化(这样你还可以根据需要做一些计算)
class Video extends React.Component {
constructor(props){
super(props);
this.state = {
loopsRemaining: this.props.maxLoops,
};
}
}

###7. 把方法作为回调提供

ES5 在ES5下,React.createClass会把所有的方法都bind一遍,这样可以提交到任意的地方作为回调函数,而this不会变化。但官方现在逐步认为这反而是不标准、不易理解的。

1
2
3
4
5
6
7
8
9
10
11
12
13
var PostInfo = React.createClass({
handleOptionsButtonClick: function(e) {
// Here, 'this' refers to the component instance.
this.setState({showOptionsModal: true});
},
render: function(){
return (
<TouchableHighlight onPress={this.handleOptionsButtonClick}>
<Text>{this.props.label}</Text>
</TouchableHighlight>
)
},
});

ES6 在ES6下,你需要通过bind来绑定this引用,或者使用箭头函数(它会绑定当前scope的this引用)来调用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class PostInfo extends React.Component
{
handleOptionsButtonClick(e){
this.setState({showOptionsModal: true});
}
render(){
return (
<TouchableHighlight
onPress={this.handleOptionsButtonClick.bind(this)}
onPress={e=>this.handleOptionsButtonClick(e)}
>
<Text>{this.props.label}</Text>
</TouchableHighlight>
)
},
}

箭头函数实际上是在这里定义了一个临时的函数,箭头函数的箭头=>之前是一个空括号、单个的参数名、或用括号括起的多个参数名,而箭头之后可以是一个表达式(作为函数的返回值),或者是用花括号括起的函数体(需要自行通过return来返回值,否则返回的是undefined)。

1
2
3
4
5
6
7
8
9
10
11
12
13
// 箭头函数的例子
()=>1
v=>v+1
(a,b)=>a+b
()=>{
alert("foo");
}
e=>{
if (e == 0){
return 0;
}
return 1000/e;
}

需要注意的是,不论是bind还是箭头函数,每次被执行都返回的是一个新的函数引用,因此如果你还需要函数的引用去做一些别的事情(譬如卸载监听器),那么你必须自己保存这个引用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
// 错误的做法
class PauseMenu extends React.Component{
componentWillMount(){
AppStateIOS.addEventListener('change', this.onAppPaused.bind(this));
}
componentDidUnmount(){
AppStateIOS.removeEventListener('change', this.onAppPaused.bind(this));
}
onAppPaused(event){
}
}
// 正确的做法
class PauseMenu extends React.Component{
constructor(props){
super(props);
this._onAppPaused = this.onAppPaused.bind(this);
}
componentWillMount(){
AppStateIOS.addEventListener('change', this._onAppPaused);
}
componentDidUnmount(){
AppStateIOS.removeEventListener('change', this._onAppPaused);
}
onAppPaused(event){
}
}
从这个帖子中我们还学习到一种新的做法:
// 正确的做法
class PauseMenu extends React.Component{
componentWillMount(){
AppStateIOS.addEventListener('change', this.onAppPaused);
}
componentDidUnmount(){
AppStateIOS.removeEventListener('change', this.onAppPaused);
}
onAppPaused = (event) => {
//把方法直接作为一个arrow function的属性来定义,初始化的时候就绑定好了this指针
}
}

###8. ES6+带来的其它好处

解构&属性延展

结合使用ES6+的解构和属性延展,我们给孩子传递一批属性更为方便了。这个例子把className以外的所有属性传递给div标签:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class AutoloadingPostsGrid extends React.Component {
render() {
var {
className,
...others, // contains all properties of this.props except for className
} = this.props;
return (
<div className={className}>
<PostsGrid {...others} />
<button onClick={this.handleLoadMoreClick}>Load more</button>
</div>
);
}
}
//下面这种写法,则是传递所有属性的同时,用覆盖新的className值:
<div {...this.props} className="override">

</div>
//这个例子则相反,如果属性中没有包含className,则提供默认的值,而如果属性中已经包含了,则使用属性中的值
<div className="base" {...this.props}>

</div>

1. 特定平台扩展名

React Native会检测某个文件是否具有.ios.或是.android.的扩展名,然后根据当前运行的平台加载正确对应的文件。
假设你的项目中有如下两个文件:
BigButton.ios.js
BigButton.android.js
这样命名组件后你就可以在其他组件中直接引用,而无需关心当前运行的平台是哪个。
import BigButton from './components/BigButton';

2. 实用的方法是Platform.select()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
var { Platform } = React;
var styles = StyleSheet.create({
container: {
flex: 1,
...Platform.select({
ios: {
backgroundColor: 'red',
},
android: {
backgroundColor: 'blue',
},
}),
},
});
//上面的代码会根据平台的不同返回不同的container样式——iOS上背景色为红色,而android为蓝色。
这一方法可以接受任何合法类型的参数,因此你也可以直接用它针对不同平台返回不同的组件,像下面这样:
var Component = Platform.select({
ios: () => require('ComponentIOS'),
android: () => require('ComponentAndroid'),
})();
<Component />;

3. 平台模块

React Native提供了一个检测当前运行平台的模块。如果组件只有一小部分代码需要依据平台定制,那么这个模块就可以派上用场。

1
2
3
4
5
import { Platform } from 'react-native';
var styles = StyleSheet.create({
height: (Platform.OS === 'ios') ? 200 : 100,
});
//Platform.OS在iOS上会返回ios,而在Android设备或模拟器上则会返回android。

4. 检测Android版本

1
2
3
4
5
//在Android上,平台模块还可以用来检测当前所运行的Android平台的版本:
import { Platform } from 'react-native';
if(Platform.Version === 21){
console.log('Running on Lollipop!');
}

摘自React Native CN

ReactNative style样式之Flexbox布局样式


Flexbox布局样式 ReactNative是参考文档大于0.29的版本


参考链接2

参考链接1

1. 6个属性设置在容器上

1.1 任何一个容器都可以指定为Flex布局。ReactNative无

display: flex;

display: inline-flex; //行内元素也可以使用Flex布局。
flex布局元素

1.2 flex-direction 属性决定主轴的方向(即项目的排列方向)。

flex-direction: row(默认值) | row-reverse | column | column-reverse;


ReactNative 中的 flexDirection: column(默认值) | column-reverse | row | row-reverse;
flex-direction 排列方向

1.3 flex-wrap 换行

flex-wrap: nowrap | wrap | wrap-reverse;


ReactNative 中的 flexWrap: nowrap | wrap ;
flex-wrap 换行

1.4 flex-flow flex-direction 和flex-wrap 的简写 ReactNative无

flex-flow : row || nowrap;
flex-flow

1.5 justify-content 水平排列方式

justify-content: flex-start | flex-end | center | space-between | space-around;
justify-content 水平排列方式


ReactNative中的 justifyContent: flex-start | flex-end | center | space-between | space-around;
justify-content 水平排列方式

1.6 align-items 垂直排列方式

align-items: flex-start | flex-end | center | baseline | stretch;
align-items 垂直排列方式


ReactNative中的 alignItems: flex-start | flex-end | center | stretch;
align-items 垂直排列方式

2. 容器中项目的属性

2.1 order ReactNative无

order :<number>; /* default 0 */属性定义项目的排列顺序。数值越小,排列越靠前,默认为0。
order

2.2 flex-grow ReactNative无

flex-grow:<number>; /* default 0 */属性定义项目的放大比例,默认为0,即如果存在剩余空间,也不放大。如果所有项目的flex-grow属性都为1,则它们将等分剩余空间(如果有的话)。如果一个项目的flex-grow属性为2,其他项目都为1,则前者占据的剩余空间将比其他项多一倍。
flex-grow

2.3 flex-shrink ReactNative无

flex-shrink: ; /* default 1 */属性定义了项目的缩小比例,默认为1,即如果空间不足,该项目将缩小。flex-basis
flex-shrink

2.4 flex-basis ReactNative无

flex-basis

2.5 flex ReactNative无

flex

2.6 align-self

align-self: auto | flex-start | flex-end | center | baseline | stretch;


ReactNative中的 alignSelf: auto | flex-start | flex-end | center | stretch;

3. FlexBox布局目前支持React Native 的属性

1
2
3
4
5
6
7
8
9
FlexBox布局目前支持React Native 的属性有如下6个:
(1) flex :number 大于0的时候才可伸缩,按照大小显示伸缩比例;
(2) flexDirection :column(容器设置的属性:主轴方向默认-垂直方向,从上倒下)| `column-reverse` | row(水平方向,从左到右)| `row-reverse`;
(3) flexWrap :wrap(换行) --nowrap(不换行)//容器设置的属性
(4) alignItems :flex-start | flex-end | center | stretch (容器设置的属性:伸缩项目在伸缩容器中的交叉轴的对齐方式);
(5) justifyContent : flex-start | flex-end | center | space-between | space-aronud (容器设置的属性:伸缩项目沿着垂直方向的对齐方式);
(6) alignSelf : flex-start | flex-end | center | auto | stretch。(伸缩项目在交叉轴的对齐方式);
(7) position : 'absolute' | 'relative' ;
(8) zIndex : number ;

组件的详细说明和生命周期(Component Specs and Lifecycle)


Mounting Cycle 挂载循环周期

  1. constructor(object props)
1
2
1. object getIniitialState() //它的返回值会成为this.state的初始值
2. object getDefaultProps() //它的返回值会成为this.props的初始值
  1. componentWillMount()//本地读取数据用于显示,进行读取的好时机
  2. render() -> React Element
  3. componentDidMount()//获取网络数据比较好的选择

Updating Cycle 组件更新循环周期

  1. componentWillReceiveProps(object nextProps)
  2. shouldComponentUpdate(object nextProps, object nextState) -> boolean
  3. componentWillUpdate(object nextProps, object nextState)
  4. render() -> React Element
  5. componentDidUpdate(object prevProps, object prevState)

1.挂载: componentWillMount

2.挂载: componentDidMount

3.更新: componentWillReceiveProps

componentWillReceiveProps(object nextProps)

4.更新: shouldComponentUpdate

boolean shouldComponentUpdate(object nextProps, object nextState)

5.更新: componentWillUpdate

componentWillUpdate(object nextProps, object nextState)

6.移除: componentWillUnmount


1.挂载: componentWillMount

1
componentWillMount()

服务器端和客户端都只调用一次,在初始化渲染执行之前立刻调用。如果在这个方法内调用 setState,render() 将会感知到更新后的 state,将会执行仅一次,尽管 state 改变了。

2.挂载: componentDidMount

1
componentDidMount()

在初始化渲染执行之后立刻调用一次,仅客户端有效(服务器端不会调用)。在生命周期中的这个时间点,组件拥有一个 DOM 展现,你可以通过 this.getDOMNode() 来获取相应 DOM 节点。
如果想和其它 JavaScript 框架集成,使用 setTimeout 或者 setInterval 来设置定时器,或者发送 AJAX 请求,可以在该方法中执行这些操作。

3.更新: componentWillReceiveProps

1
componentWillReceiveProps(object nextProps)

在组件接收到新的 props 的时候调用。在初始化渲染的时候,该方法不会调用。
用此函数可以作为 react 在 prop 传入之后, render() 渲染之前更新 state 的机会。老的 props 可以通过 this.props 获取到。在该函数中调用 this.setState() 将不会引起第二次渲染。

1
2
3
4
5
componentWillReceiveProps: function(nextProps) {
this.setState({
likesIncreasing: nextProps.likeCount > this.props.likeCount
});
}

4.更新: shouldComponentUpdate

1
boolean shouldComponentUpdate(object nextProps, object nextState)

在接收到新的 props 或者 state,将要渲染之前调用。该方法在初始化渲染的时候不会调用,在使用 forceUpdate 方法的时候也不会。
如果确定新的 props 和 state 不会导致组件更新,则此处应该 返回 false。

1
2
3
shouldComponentUpdate: function(nextProps, nextState) {
return nextProps.id !== this.props.id;
}

如果 shouldComponentUpdate 返回 false,则 render() 将不会执行,直到下一次 state 改变。(另外,componentWillUpdate 和 componentDidUpdate 也不会被调用。)
默认情况下,shouldComponentUpdate 总会返回 true,在 state 改变的时候避免细微的 bug,但是如果总是小心地把 state 当做不可变的,在 render() 中只从 props 和 state 读取值,此时你可以覆盖 shouldComponentUpdate 方法,实现新老 props 和 state 的比对逻辑。
如果性能是个瓶颈,尤其是有几十个甚至上百个组件的时候,使用 shouldComponentUpdate 可以提升应用的性能。

5.更新: componentWillUpdate

1
componentWillUpdate(object nextProps, object nextState)

在接收到新的 props 或者 state 之前立刻调用。在初始化渲染的时候该方法不会被调用。
使用该方法做一些更新之前的准备工作。

6.移除: componentWillUnmount

1
componentWillUnmount()

在组件从 DOM 中移除的时候立刻被调用。
在该方法中执行任何必要的清理,比如无效的定时器,或者清除在 componentDidMount 中创建的 DOM 元素。

Hexo 博客的安装流程

1. 配置环境

因为本人是用 Mac 所以就以主要介绍 Mac 的环境为主;

1.1 安装 Node 环境

作用:用来生成静态页面的

方法1. 直接上 https://nodejs.org/ 官网下载安装

方法2. Homebrew 安装
Homebrew 是 Mac 系统的包管理器,用于安装 NodeJS 和一些其他必需的工具软件。

首先, 安装 Homebrew;

1
/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

复制上面代码在终端里面运行,等待安装完毕;

接下来在用 Homebrew 安装 Node;

1
brew install node

复制上面代码在终端里面运行,等待安装完毕;

1.2 Github 或者 Coding 账户都可以

作用:是用来做博客的远程创库、域名、服务器之类的,怎么与本地hexo建立连接等下讲。

2. 正式安装 Hexo

2.1 安装 Hexo 的命令行工具

1
npm install -g hexo

复制上面代码在终端里面运行,等待安装完毕;

2.2 初始化博客

1
hexo init 你的博客名

在终端中前往你要放置博客的文件夹位置, 运行上面代码,等待安装完毕;

2.3 配置 Github 仓库

登录到你自己的 github 账号, 点击 new repository 开始创建仓库, 按照下面的填写你自己要的参数;
创建仓库
配置 github pages 页面, 点击 Settings , 在 GitHub Pages 中开启配置为主分支
配置 github pages

2.4 配置 Hexo 文件

打开 Hexo 创建的根目录下的 _config.yml 文件,主要配置如下
_config.yml 文件

1
2
3
4
5
6
7
# Site
title: you blog // 你博客的名称标题
subtitle: // 你博客的小标题(选填)
description: 好好过一生 // 博客的描述,可以写短小的座右铭
author: FerryVip // 作者你的名字
language: zh-Hans // 设置博客的语音(选填,默认英文)
timezone: // 时区(选填)
1
2
3
4
5
# Deployment
deploy:
type: git // 类型就填 git
repo: git@github.com:strawferry/FerryBlog.git // 你的仓库地址,在配置 github 仓库成功后会有,可以用 HTTPS (需要输入密码登录)和 SSH(需要配置SSH)
branch: master // 默认主分支
1
npm install hexo-deployer-git --save

复制上面代码在终端的 hexo 目录下里面运行,等待安装完毕;

2.5 node 生成静态文件

hexo generate 或者 hexo g

复制上面代码在终端的 hexo 目录下里面运行,等待运行完毕;

2.6 本地运行查看

1
2
3
hexo server
或者
hexo s

复制上面代码在终端的 hexo 目录下里面运行,等待运行完毕, 显示通过访问 http://localhost:4000/ 就可以预览博客;

2.6 上传博客文件到 github

1
2
3
hexo deploy
或者
hexo d

复制上面代码在终端的 hexo 目录下里面运行,等待运行完毕;
等待运行完毕基本就能访问刚才在 github 配置 pages 的链接了;

2.7 编写你的博客

1
hexo new "new article"

之后在source/_posts目录下面,多了一个new-article.md的文件。
你通过编辑 new-article.md 就可以写你的日记了;

2.8 一些常用的命令

hexo clean // 清除文件

hexo generate // 生成静态文件

hexo deploy // 部署代码上去

hexo new "文章标题" // 创建新文章

3. 配置 Hexo 主题

官方默认主题你懂得,不怎么好看,果断自己换个,本人觉得 next 的主题还可以,这边就以配置这个主题举个栗子;
官方使用文档

主题下载

git clone https://github.com/iissnan/hexo-theme-next themes/next

复制上面代码在终端的 hexo 目录下里面运行,等待下载完毕;

主题更改

1
2
3
4
# Extensions
## Plugins: https://hexo.io/plugins/
## Themes: https://hexo.io/themes/
theme: landscape // 改为 next

到此基本配置 Hexo 和 主题更换已经都会了,要更好使用,还需要自己看下文档去详细配置;

说说之前配置遇到的一个坑, 前面我没有说到,就是要等大家都配置完了,大伙也会碰到的问题,在最后给大家说一下

就是在本地跑 hexo server 一切看起来都好好的,样式都没啥问题, 当去看 pages 的时候,发现样式惨不忍睹,这就对了,因为还有一个东西还没有配置;

1
2
3
4
5
6
# URL
## If your site is put in a subdirectory, set url as 'http://yoursite.com/child' and root as '/child/'
url: http://yoursite.com // 把你在 pages 配置的那个网址链接复制在这个地方就解决了
root: /
permalink: :year/:month/:day/:title/
permalink_defaults: