1.前言
ReactNative,简称RN,是使用JavaScript和React编写跨平台原生移动应用的一门语言
。这篇文章会围绕ReactNative前期开发需要的知识点做个简单铺垫。
2.TypeScript语言
2.1 简介
TypeScript,简称TS,由微软开发的开源的编程语言,最新的版本是3.x。TypeScript本质是 JavaScript 的超集,可以编译成JavaScript。
目前也是写ReactNative的语言。
TypeScirpt相比JavaScript有以下优点:
- 强类型,静态类型检查,可以在编译阶段就发现大部分错误;
- 增强了编辑器和 IDE 的功能,包括代码补全、语法提示;
- 更具备面向对象写法;
- ……
2.2 基础语法
这里列举TS基础语法:变量、函数以及类。
1.变量
let/var/const name:string = 'hello world'
const、let、var
- const声明常量,初始化后不可修改,let、var声明的变量可修改;
- let和const声明的变量无法跨越块作用域,诸如if和for等都是块作用域。所以在for循环中的自增自减量用let会很方便,var则是非块作用域;
变量类型
- 冒号后面是类型注解,JavaScript 的类型分为两种:原始数据类型和对象类型。
原始数据类型包括:boolean、number、string、null、undefined 以及 ES6 中的新类型 Symbol非必写;其他类型包括有array、Tuple、Enum、Any、Object、void、never、交叉类型、联合类型等; - 如果没有声明类型,则会在赋值后进行类型推论,如赋值3,则推测是number。
2.函数
# 定义函数
fun1(name:string, age:number =18, data?:any,callBack?:Function,){
console.log('传入参数name为'+name)
if(callBack){
callBack();
}
return "hello,"+ name;
}。
# 使用函数
fun1('zhangsan',data,()=>{
console.log(‘回调’)
})
函数参数
- 参数冒号后面是对应参数类型;
- 必须参数name,该参数必传;
- 可选参数data,问号表示是可选参数,参数非必传;可选参数必须在必须参数后面;
- 默认参数age,允许不放在必须参数后面,不传时默认为18。如果默认参数在必须参数前面,需要传入undefined,如fun1('zhangsan',undefined, data);
- callBack参数是一个函数,需要回调时除了return也可传入一个回调函数;
- 稍复杂的还有箭头函数、异步函数,结合promise处理等,这里不展开讲。
3.类
# 定义
class People{
private age:string = 18
public name:string = 'zhangsan'
protected sex:SexType = SexType.male
readonly weight:number = 100
tall:number = 155
constructor(age:number) {
this.age = number
}
static className: String = 'People' //静态成员
static consoleMethod(){ //静态方法
console.log('consoleSomething')
}
parseNetData = (data:any)=>{//对象方法
this.name = data.name
}
}
# 继承
class Student extends people{
let grade:number
let classes:number
}
# 使用
let people = new People(18)
people.parseNetData('张三')
People.consoleMethod()
说明:
- constructor是构造方法,非必写;
- private修饰的成员只能在类的内部访问;protected修饰的属性和private 类似,区别是它在子类中也是允许被访问的;public修饰的属性或方法是公有的,在任何地方被访问到,默认所有的属性和方法都是 public 的;
- readonly修饰成员weight表示属性只读,不能通过people.weight=120修改对象属性;
- static修饰的方法和变量称为静态方法和静态变量,静态变量内存在该类中只创建一份;静态方法不能访问非静态成员和非静态方法;
实际上述类本质上会编译成如下JS代码,可以通过TS编译成JS网址一窥TS本貌。
var People = /** @class */ (function () {
function People(age) {
var _this = this;
this.age = 18;
this.name = 'zhangsan';
this.sex = SexType.male;
this.weight = 100;
this.tall = 155;
this.parseNetData = function (data) {
_this.name = data.name;
};
this.age = number;
}
People.consoleMethod = function () {
console.log('consoleSomething');
};
People.className = 'People'; //静态成员
return People;
}());
更多TS语法可查阅TS手册指南。
2.3 tsconfig.json
项目的根目录一般存放一个tsconfig.json的TypeScript配置文件,tsconfig.json文件中指定了用来编译这个项目的根文件和编译选项。
# tsconfig.json示例
{
"exclude": [“node_modules","src/libs/**"],
"compilerOptions": {
"target": “es2017", //指定ECMAScript的目标版本,"ES3"(默认),"ES5","ES6","ES2015"等
"module": “commonjs”, //指定模块代码生成:"None""CommonJS""AMD""System""UMD""ES6""ES2015""ESNext"
"outDir": “./dist/out/", //讲输出结构重定向到目录
"jsx": “react", //支持JSX的.tsx文件
"strict": true , //启用所有严格类型检查选项
"allowSyntheticDefaultImports": true , //允许没有默认到处的模块进行默认导入
"experimentalDecorators": true //为ES装饰器启用实验支持
}
}
3. UI相关
3.1 JSX
简介
JSX全称是JavaScript XML,React 使用 JSX 来替代常规的 JavaScript 描述UI界面
。JSX并不是React必须使用的,但React官方建议我们使用 JSX, 因为它能定义简洁且我们熟知的包含属性的树状结构语法。
使用
- 基础使用
# 示例
<View style={styles.container} >
<Text >标题</Text>
<Text>内容</Text>
</View>
上面代码View和Text都是系统自带组件,表示一个View视图里包含多个Text,View内部的style是样式属性,决定着它的样式和布局,这就是一个基本清晰的UI描述。
- 嵌入表达式
大部分时候视图需要根据传入的数据状态发生改变,这时候可以嵌入表达式进行处理。
render(){ //渲染函数,返回渲染的
return(
<View>
<Text>测试</Text>
<Text>{this.props.title}</Text>
{this.props.showLastText && <Text>{this.props.title}</Text >} //
{this.props.showText?<Text>{this.props.title}</Text >:null}
</View>
)
}
{}里面放的是表达式,结果返回视图元素
第二行&& 与运算符
是根据属性showLastText判断,为true时&& 右侧的元素就会被渲染,否则这位置不会渲染任何东西;
第三行用的是三目运算符
,Text元素里面显示的是传进来的属性标题,没有则返回null,null表示这个这位置不会渲染任何东西。这也是最常用的几种条件渲染
方式。
- 数据源生成视图
有时候需要拿到具体的数据源,生成对应的视图。例如根据数据的个数生成对应多个Text,我们可以这样处理。
render(){
return(
<View>
<Text>测试</Text>
<Text>{this.props.title}</Text>
{this.renderDataView()}
</View>
)
}
renderDataView(){
const data = this.getData()//获取数据源
const elements = []
for (let i = 0; i < data.length; i++) {
let subTitle = (
<View>
<Text> {data[i].title} </Text>
</View>
)
elements.push(subTitle)
}
return elements
}
getData(){
return ['1','2','3','4'];
}
在表示式中调用renderDataButtons函数,函数内部会拿到data数据源,根据数据源生成对应的视图并返回。
需要注意的是:
- 编写javascript的文件使用.js扩展名,编写TypeScript的文件使用.ts扩展名,而编写JSX则使用.tsx扩展名。
本质
究其本质,JSX就是React使用来描述UI的语法糖
,最终会转成Javascript。可以用Bable做个转换,如下面两种代码的作用是完全相同的。
const element = (
<h1 className="greeting">
Hello, world!
</h1>
);
# 上面代码编译如下
const element = React.createElement(
'h1',
{ className: 'greeting' },
'Hello, world!'
);
3.2 CSS
当我们用JSX写了各种各样视图元素后,还需要告知系统它们的样式和相互之间的层次布局
。这里就会用到了CSS(样式表)。
Style便是RN需要传入作为布局样式的属性
,传入Style的方式主要有:
- 直接写在对象内部
- 创建样式表进行引用
# (1)直接写在内部,这里需要加多一层{}
<Text style={{fontSize:'16',textAlign:'center'}}>标题</Text>
# (2)在外部使用StyleSheet创建一个样式表对象styles存储所有style
<Text style={styles.title}>标题</Text>
...
const styles = StyleSheet.create({
title: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
},
subTitle: {
backgroundColor: 'red',
},
})
有时候,我们会拿到数据源后才能决定样式,可以这样处理。
# 渲染函数内部
……
let optionSytles //style准备用变量optionSytles存储
if(data.isRedColor){
optionSytles = {backgroundColor: 'red'}
}
……
# 这里可以用一个[]存一个数组style,并放入optionSytles变量,最终optionSytles可能为红色背景或者空
<Text style={[{fontSize:'16',textAlign:'center'},optionSytles]}>标题</Text>
需要注意的是:
推荐使用StyleSheet创建样式表对象供组件引用,这样能做到统一管理,代码层次清晰。
JSX中的style属性应该作为一个对象,因为对象是JavaScript的语法,因此又应该需要大括号包围。同时,css属性也不是使用划线连接,而是使用驼峰形式。`
3.3 Flexbox
CSS3引入了一种新的布局模型——Flexbox(弹性布局)
。如果是从客户端转过来的童鞋,不一定熟悉弹性布局,当熟悉之后则会喜欢上这种布局。因为网上已经有非常好的相关教程,这里不重复造轮子。具体可参考:
其它布局
绝对布局,相对于父级元素的左上角为原点来定位。
{position: 'absolute',top:20,width: 50, height: 50'}百分比布局,占父级元素的百分比。
{width: '30%', height: '50%'}……
3.4 API查询
RN的样式基本上是实现了 CSS 的一个子集。对于初学者来说,苦于不清楚各个组件样式API而无从下手,其实RN中文网已经提供我们大部分样式表API查询,样式表的链接附在本文的最后面。
3.5 牛刀小试
最后贴两个链接,网站里面嵌有expo,对RN项目还不熟的童鞋可以先尝试着在这里写些Style & FlexBox布局。
4. 包管理
RN用的包管理器
是npm 或者 yarn 。
4.1 npm
当我们需要引入第三方模块时,经常看到安装指引经常让我们输入npm install
命令,这就是npm的模块安装命令。如下所示:
# 会把模块安装到node_modules目录中,不会修改package.json
$ npm install XX
# save 的意思是将模块安装到项目目录下,并在package文件的dependencies节点写入依赖。
$ npm install --save XX
# 将模块安装到项目目录下,并在package文件的devDependencies节点写入依赖。
$ npm install --save-dev XX
如果我们还没安装npm,可以先安装npm。
# 安装nodejs,npm 是node.js自带的功能。
$ brew install node
4.2 package.json配置文件
一般每个项目的根目录下面,会有一个package.json文件,该文件定义了这个项目所需要的各种模块,以及项目的配置信息(比如名称、版本、许可证等元数据)
。
package.json文件内部是json格式,常见配置信息如下:
{
"name": "demo", #包名
"version": "1.0.0",#包的版本号
"description": "", #包的描述
"main": "index.js",#指定了程序的主入口文件
"dependencies": {#包依赖
"react-native": "0.58.5",
},
"devDependencies": {
"mobx": "4.9.2",
"mobx-react": "^5.4.3"
},#包依赖
"scripts": { #脚本
"start": "node index.js",
}
}
需要解释的是:
- main:指定了程序的主入口文件,这个字段的默认值是模块根目录下面的 index.js;
- dependencies:运行时的依赖,发布后,即生产环境下还需要用的模块,安装在 node_module 目录下;
- devDependencies:开发时的依赖。里面的模块是开发时用的,发布时用不到它,安装在 node_module 目录下;
- scripts:指定了运行脚本命令的npm命令行缩写,比如start指定了运行npm run dev-ios时,相当执行react-native run-ios命令,"dev-ios": "react-native run-ios";
与包管理相关的操作:
- 每一次npm install --save XX或者npm uninstall --save都会把更改的配置记录在该文件里。
- 当执行npm install命令时,会根据package.json文件配置,自动下载所需的模块到项目根目录里的node modules。
4.3 Yarn
Yarn是 Facebook 提供的替代 npm 的工具,可以加速 node 模块的下载。React Native 的命令行工具用于执行创建、初始化、更新项目、运行打包服务(packager)等任务。简单说yarn对比npm更快更安全,推荐在RN开发中用yarn代替npm。
安装
# Homebrew 安装 yarn
brew install yarn
安装完成后就可以用 yarn 代替 npm 了,例如用yarn
代替npm install
命令。
4.4 常见命令
npm | yarn | 含义 |
---|---|---|
npm install | yarn | 根据package.json配置,下载所需模块包到node_modules |
npm install react --save | yarn add react | 下载react包,并记录在package.json配置文件dependencies里 |
npm install react --save-dev | yarn add react --dev | 下载react包,并记录在package.json配置文件devDependencies里 |
npm uninstall react --save | yarn remove react | 卸载react包 |
npm config set registry XX | yarn config set registry XX | 设置源为淘宝源 |
npm config list | yarn config get registry | 查看一下当前源 |
5. Babel
Babel 是一个 JavaScript 编译器,主要用于将 ECMAScript 2015+ 版本的代码转换为向后兼容的 JavaScript 语法,以便能够运行在当前和旧版本的浏览器或其他环境中。
Babel 同时也能够转换 JSX 语法和TS语法,更多可通过Babel编译器网址一窥TSX本貌。
Babel的配置文件是.babelrc,存放在项目的根目录下,Babel有关规则都会写入.babelrc文件里。
6. webPack
webpack 是一个JavaScript 应用程序的静态模块打包器(module bundler)。当 webpack 处理应用程序时,它会递归地构建一个依赖关系图(dependency graph),其中包含应用程序需要的每个模块,然后将所有这些模块打包成一个或多个 bundle。
一般项目中都会使用webpack对代码进行打包,比如,将多个js文件打包成1个js文件,这样可以减少前端的资源请求。
总结
工欲善其事,必先利其器。这篇文章主要写ReactNative开发中前期需要接触到的基本知识点,相信前端同学对这些知识大部分都不陌生。对于客户端同学来说,在刚开始学习有了这部分前端知识储备,对后面学习ReactNative会有更好的帮助和理解,最后用一个表格来总结这篇文章的内容。
内容 | 资源链接 |
---|---|
JavaScript API查询 | JavaScript 标准内置对象 |
TypeScript语法 | TS手册指南 |
样式API | View样式 |
Text样式 | |
Image样式 | |
阴影样式 | |
FlexBox布局 | 布局样式 |
Flex 布局教程:语法篇 | |
Flex 布局教程:实例篇 | |
FlexBox Docs | |
React语法 | React官网 |
ReactNative语法 | React Native中文网 |
Npm | npm 中文文档 |
Yarn | yarn 中文文档 |
Bable(了解) | Bable试一试 |
webpack(了解) | webpack官网 |