ReactJS+ReactNative笔记

依然范特西╮ 提交于 2020-02-23 04:46:13

1.移动App第1天

什么是混合移动App开发【重点】

  1. 苹果上的软件是如何开发出来的:使用的是 OC、或者使用Swift这门语言
  2. 安卓平台上的软件又是如何开发出来的:使用安卓相关的语言开发的,Java,安卓的控件进行开发
  3. 苹果和安卓平台上共有的软件是如何开发出来的:腾讯招两套开发人员【开发组】,手机京东
  4. 前端移动 App(Application)开发技术,去开发手机端的应用程序;
  5. 前端的混合移动App开发技术,并没有使用 苹果 或 安卓 官方推荐的 开发平台和开发方式,而是抛弃了 官方提供的方式,使用 前端的独有的技术进行移动App开发体验;

什么是移动App开发:通俗的理解,就是把开发Web网站的技术(HTML+CSS+JS),通过某种方式,移植到移动App开发上进行使用,这种利用Web开发技术进行移动端开发体验的方式,叫做混合移动App开发!

关于移动App开发,需要知道的几个概念:

  • 原生开发:它的英文单词是(NativeApp),指的就是使用 IOS、Android 官方提供的工具、开发平台、配套语言进行 手机App开发的方式;
  • 混合开发:(HybirdApp)就是使用前端已有的技术,HTML + CSS + JS ,然后再搭配一些相关的打包编译技术,就能够开发出一个手机App,安装到手机中进行使用;
  • 什么是App:App是(Application的缩写),意思是:可安装的应用程序;
  • App的分类:
    • 按照平台来划分:
      • PC端:浏览器、代码编辑器、PC端的游戏、听歌的、看视频的、聊天的
      • 移动端:手机QQ、手机微信、手机爱奇艺、亡者农药
    • 按照功能来划分:
      • 游戏:愤怒的小鸡仔、植物大战僵尸、亡者农药…LOL
      • 应用:非游戏类的软件,支付宝、陌陌、美团外卖、
  • App和Web的区别:
    • APP概念:App是(Application的缩写),意思是:可安装的应用程序;
    - 优点:流畅、稳定、基本上一些App都可以脱网运行,用户体验好;
    - 缺点:不能跨平台
    
    • Web概念:特指那些基于浏览器的web网站(本质:就是网页)
    - 优点:可以跨平台(浏览器天生就是跨平台的)
    - 缺点:没有App流畅、不稳定,受限于网速和网络
    

为什么要学混合App开发

从程序员的角度分析:

  1. 挣钱多(别人不会的你会,别人会的,你精通)
  2. 对于找工作来说:(React Native)市场需求量大,好找工作,提高我们的行业竞争力
  3. 能接触到前端流行的技术和框架(各大公司基本都再用React),注意:再React中我们全部都使用ES6语法(class)
  • 前端是一个永恒的行业???(只要世界上还有浏览器的存在,必然需要前端,只不过,随着时间的推移,技术更新换代,可能我们对新技术的要求会越来高)
  • 屌丝的崛起之路:只能做页面 -> Ajax前后台数据交互 -> Jquery、Bootstrap -> webApp -> 三大框架 -> 可以做手机混合App/桌面应用 -> 可以做手机原生App -> 将来或许可以发射火箭发射卫星发射导弹 -> 终极目标:统一全宇宙
  1. (搞前端App开发)能购置一批牛逼的设备【苹果笔记本、IOS测试机、安卓手机(三星的、华为、小米)】

从企业的角度分析:(选择合适自身的移动App开发方式)【重点】

  • 节省开发成本
  • 从工资上:尽最大的可能,压榨员工的剩余劳动力
  • 从时间上:因为 原生的安卓和IOS开发,它们的开发效率并不是很高,因为原生的代码复杂度比较高,因此原生的开发周期比较慢;如果采用移动App开发,那么,我们的开发周期会很短;因为 HTML + CSS + JS 足够简单;(对于前端开发APP来说,有两种方式,其中,比较早的一种,也是比较简单的一种,就是 先开发出一个网站, 然后再把网站运行一行打包的命令,就能得到一个 APP了)
  1. 市面上常见的App开发方式
  • WebApp:基于浏览器实现的,有特定功能的网站,称作WebApp
    • 例如:百度脑图、https://m.jd.com/、https://m.taobao.com/#index
    • 优点:跨平台
    • 缺点:依赖网络,有白屏效果,相对来说,用户体验差;不能调用硬件底层得设备,比如摄像头;
  • NativeApp:用android和Object-C等原生语言开发的应用
    • 优点:体验好;用户使用起来很流畅;非常适合做游戏【性能高】;可以直接调用硬件底层的API;
    • 缺点:不能跨平台
  • HybirdApp:利用前端所学的知识去开发移动端App,兼具2者的优势
    • 优点:能够跨平台;体验会好一些;也能够调用硬件底层的API
    • 缺点:相对于原生体验稍微弱一丢丢;不适合做游戏;适合做非游戏类型的手机App;
    • 应用场景:
  • 注意: 使用 Java 或者 IOS 写出来的代码和程序,在最终运行的时候,普通的文本代码,都会被编译为 原生的机器码去运行,并不像 JS 这样,解析执行,Java代码是 编译执行的;
  1. 三种开发方式的原理和对比

三种开发类型的原理.png

三种开发类型的对比.png
3. 谁在使用React Native???

企业如何选择合适自己的App开发方式

  1. 如果这个企业中,曾经使用原生技术开发过一些APP,那么在维护的时候,必然需要使用原生技术来维护
  2. 如果企业中,需要做一些游戏级别的应用,那么推荐使用原生,因为原生运行效率高,对耗电量处理的很好;
  3. 如果企业做一些应用级别的非游戏软件,比如 淘宝、京东、美团,就可以使用 混合APP了;
  4. 在企业中,最主要的是好的点子,如果有了一个好的项目立案,那么最好要立即把这个项目做出来;这时候,使用混合App非常合适,因为开发周期很短,能快速上线,抢先占领市场;【裤衩开发】

企业中项目开发流程

  • 需求调研:产品定位、受众群体、市场需求、开发价值;【产出物:需求文档】
  • 产品设计:功能模块、流程逻辑;【产出物:设计文档,交互稿】,确定项目的基本功能;
  • 项目开发:项目架构、美工、前端、后台、测试【产品的把控】要理解前后端分离的概念
  • 运营维护:上线试运行、调Bug、微调功能模块、产品迭代

根据需求搞设计,根据设计做开发

企业技术选型 - 几大主流技术之间的关系

  1. Angular.js 和 Ionic
  1. Vue.js 和 Weex
  1. React.js 和 React-Native

Angular, Vue, React 这三个都是前端框架,我们在进行混合App开发的时候,只是用到了这三个框架的【基础语法】而已;
Ionic, Weex, ReactNatvie 这三个都是打包工具(提供了相关的命令行,只要运行指定的命令,就能够把项目打包成一个手机App出来),能够把我们开发出来的应用,最终打包成一个可安装的手机端程序安装包;同时,这三个东西,也提供了好用的一些小组件,方便我们去构建移动App的用户界面;

前端混合App开发框架

  1. Html5+、ReactNative、Weex、Ionic
  2. 认识HTML5+
  • h5+是一个产业联盟,它有一些互联网成员,专门在中国推广H5
  1. HBuilder官网

开发框架之间的区别

  1. Html5+ 和 Ionic
  2. ReactNative 和 Weex

使用HBuilder生成安卓应用(在线)

API地址
Hbuilder这个工具,是一个在线打包工具,使用很方便,不需要在本地配置开发环境;直接将做好的网站,通过一些简单的操作,就能在线打包为一个App出来;

  • 在项目上右键 -> 发行 -> 发行为原生安装包

好处:本地不用配置开发环境;操作方便,对于程序员来说不关心打包的过程,打包过程对于我们来说是透明的;
缺点:程序员很少能干预打包的过程;源代码被提交到了云端的服务器,存在项目核心代码被泄露的风险;

环境变量的使用

作用:将需要全局使用的工具或者应用程序,配置到Path环境变量中,可以很方便的通过命令行的形式,在任何想要运行这些应用程序的地方,运行它们;

移动App开发环境配置【重点】

安装最新版本的java jdk

  1. 修改环境变量,新增JAVA_HOME的系统环境变量,值为C:\Program Files (x86)\Java\jdk1.8.0_112,也就是安装JDK的根目录
  2. 修改系统环境变量Path,在Path之后新增%JAVA_HOME%\bin;%JAVA_HOME%\jre\bin;
  3. 新建系统环境变量CLASSPATH,值为.;%JAVA_HOME%\lib\dt.jar;%JAVA_HOME%\lib\tools.jar;
  4. 保存所有的系统环境变量,同时退出系统环境变量配置窗口,然后运行cmd命令行工具,输入javac,如果能出现javac的命令选项,就表示配置成功!

安装Node.js环境

注意:需要安装最新的长期稳定版本,不要实验版本;安装完毕之后的node.js会自动配置到全局系统环境变量中
安装完毕后,可以输入node -v查看node版本号;

安装C++环境

大多数情况下操作系统自带C++环境,不需要手动安装C++环境;
如果运行报错,则需要手动安装visual studio中的C++环境;

安装Git环境

Git安装完毕后,会自动配置到系统环境变量中;
可以通过运行git --version来检查是否正确安装和配置了Git的环境变量;

安装Python环境

  1. 注意:安装Python时候,只能安装2.×的版本,注意勾选安装界面上的Add Python to path,这样才能自动将Python安装到系统环境变量中;
  2. 安装完毕之后,可以在命令行中运行python,检查是否成功安装了python。

配置安卓环境

  1. 安装installer_r24.3.4-windows.exe,最好手动选择安装到C盘下的android目录
  2. 打开安装的目录,将android-25android-23(react-native必须依赖这个)解压后,放到platforms文件夹下
  3. 解压platform-tools,放到platform-tools文件夹下
  4. 【这一步直接忽略即可!】tools文件夹不解压覆盖也行;解压tools,放到安装根目录中
  5. 解压build-tools_r23.0.1-windows.zip(react-native必须依赖这个)build-tools_r23.0.2-windows.zip(weex必须依赖这个)build-tools_r23.0.3-windows.zip,并将解压出来的文件夹,分别改名为版本号23.0.123.0.223.0.3;在安装目录中新建文件夹build-tools,并将改名为版本号之后的文件夹,放到新创建出来的build-tools文件夹下
  6. 在安装目录中,新建extras文件夹,在extras文件夹下新建android文件夹;解压m2responsitory文件夹和support文件夹,放到新建的extras -> android文件夹下
  7. 配置安装环境变量:在系统环境变量中新建ANDROID_HOME,值为android SDK Manager的安装路径C:\Users\liulongbin\AppData\Local\Android\android-sdk,紧接着,在Path中新增;%ANDROID_HOME%\tools;%ANDROID_HOME%\platform-tools;

ReactNative快速打包

  1. 安装完node后建议设置npm镜像以加速后面的过程(或使用科学上网工具)。注意:**不要使用cnpm!**cnpm安装的模块路径比较奇怪,packager不能正常识别!

npm config set registry https://registry.npm.taobao.org --global

npm config set disturl https://npm.taobao.org/dist --global

  1. Yarn、React Native的命令行工具(react-native-cli)
  • Yarn是Facebook提供的替代npm的工具,可以加速node模块的下载。React Native的命令行工具用于执行创建、初始化、更新项目、运行打包服务(packager)等任务。

npm install -g yarn react-native-cli

  • 安装完yarn后同理也要设置镜像源:

yarn config set registry https://registry.npm.taobao.org --global

yarn config set disturl https://npm.taobao.org/dist --global

  1. 运行react-native init AwesomeProject创建React-Native项目
  2. 运行cd AwesomeProject切换到项目根目录中,运行adb devices来确保有设备连接到了电脑上
  3. 运行react-native run-android打包编译安卓项目,并部署到模拟器或开发机中
  4. 运行上一条命令之前,要确保有设备连接到了电脑上,可以运行adb devices查看当前接入的设备列表,打包好的文件,放到了android\app\build\outputs\apk目录下
  5. 入坑指南

问题1:开启悬浮框权限;

问题2:Could not get BatchedBridge, make sure your bundle is packaged correctly

解决方案:在终端中,进入到项目的根目录,执行下面这段命令行:

react-native bundle --platform android --dev false --entry-file index.android.js --bundle-output android/app/src/main/assets/index.android.bundle --assets-dest android/app/src/main/res/

运行之前,需要确保android/app/src/main/目录下有assets文件夹,如果没有,手动创建之~,再运行上面的命令;

问题3:could not connect to development server

解决方案:晃动手机,唤起设置属性窗口,点击“Dev settings”,再点击Debuug server host 出现设置ip地址窗口,填写Ip地址和端口号8081,例如192.168.1.111:8081

Weex快速打包

  1. 安装依赖:Weex 官方提供了 weex-toolkit 的脚手架工具来辅助开发和调试。首先,你需要最新稳定版的 Node.js 和 Weex CLi。
  2. 运行npm install -g weex-toolkit安装Weex 官方提供的 weex-toolkit 脚手架工具到全局环境中
  3. 运行weex create project-name初始化Weex项目
  4. 进入到项目的根目录中,打开cmd窗口,运行weex platform add android安装android模板,首次安装模板时,等待时间较长,建议fq安装模板
  5. 打开android studio中的安卓模拟器,或者将启用USB调试的真机连接到电脑上,运行weex run android,打包部署weex项目
  6. 部署完成,查看项目效果

总结重点

  1. 什么是前端移动App开发
  2. 市面上常见的App开发方式及优缺点
  3. 使用Hbuilder在线生成安卓应用
  4. 学会配置ReactNative开发环境
  5. 掌握ReactNative打包流程

2.移动App第2天

webpack的发布策略

  1. 在实际开发中,一般会有两套项目方案:
  • 一套是开发期间的项目,包含了测试文件、测试数据、开发工具、测试工具等相关配置,有利于项目的开发和测试,但是这些文件仅用于开发,发布项目时候需要剔除;
  • 另一套是部署期间的项目,剔除了那些客户用不到的测试数据测试工具和文件,比较纯净,减少了项目发布后的体积,有利于安装和部署!
  1. 为了满足我们的发布策略,需要新建一个配置文件,命名为webpack.publish.config.js,将webpack.config.js的配置拷贝过去,剔除一些开发配置项即可:
  • devServer节点删掉:
devServer: {
       hot: true,
       open: true,
       port: 4321
   }
  • plugins节点下的热更新插件删掉:
new webpack.HotModuleReplacementPlugin()
  1. 修改url-loader,将图片放入统一的images文件夹之下:
{ test: /\.(png|jpg|gif)$/, use: 'url-loader?limit=43959&name=images/[name].[ext]' }

或者使用img-前缀加上7位的hash名称

{ test: /\.(png|jpg|gif)$/, use: 'url-loader?limit=43959&name=images/img-[hash:7].[ext]' }
  1. package.json中的script节点下新增dev命令,通过--config指定webpack启动时要读取的配置文件:
"pub": "webpack --config webpack.publish.config.js"

每次重新构建时候删除dist目录

  1. 运行cnpm i clean-webpack-plugin --save-dev
  2. 在头部引入这个插件:
var cleanWebpackPlugin = require('clean-webpack-plugin');
  1. plugins节点下使用这个插件:
new cleanWebpackPlugin(['dist'])

分离第三方包改造webpack.publish.config.js

  1. 改造entry节点如下:
entry: {
        app: path.resolve(__dirname, 'src/js/main.js'), // 自己代码的入口
        vendors: ['jquery'] // 要分离的第三方包的入口
    }
  1. 在plugins节点下新增插件:
new webpack.optimize.CommonsChunkPlugin({ // 抽离第三方包的插件
        name:'vendors', // 指定抽离第三方包的入口名称
        filename:'vendors.js' // 抽离出的公共模块的名称
})
  1. html-webpack-plugin在生成index.html文件的时候,会自动将抽离的第三方包引入进去!

优化压缩JS

在plugins数组中添加:

new webpack.optimize.UglifyJsPlugin({ // 优化压缩JS
    compress:{
        warnings:false // 移除警告
    }
}),
new webpack.DefinePlugin({ // 设置为产品上线环境,进一步压缩JS代码
    'process.env.NODE_ENV': '"production"'
})

优化压缩HTML文件

plugins节点下的htmlWebpackPlugin插件中,添加minify子节点:

minify:{// 压缩HTML代码
    collapseWhitespace:true, // 合并空白字符
    removeComments:true, // 移除注释
    removeAttributeQuotes:true // 移除属性上的引号
}

其他优化项请参考:html-minifier - github

抽取CSS文件

  1. 运行npm install --save-dev extract-text-webpack-plugin安装抽取CSS文件的插件。
  2. 在配置文件中导入插件:
const ExtractTextPlugin = require("extract-text-webpack-plugin");
  1. 修改CSS和Sass的loader如下:
{
    test: /\.css$/, use: ExtractTextPlugin.extract({
        fallback: "style-loader",
        use: ["css-loader"],
        publicPath: '../' // 设置图片路径
    })
},
{
    test: /\.scss$/, use: ExtractTextPlugin.extract({
        fallback: "style-loader",
        use: ['css-loader', 'sass-loader'],
        publicPath: '../' // 设置图片路径
    })
}
  1. 在plugins节点下新增插件:
new ExtractTextPlugin("css/styles.css"), // 抽取CSS文件的插件

压缩抽取出来的CSS文件

  1. 运行cnpm i optimize-css-assets-webpack-plugin --save-dev安装插件到开发依赖。
  2. 在配置文件头部导入插件:
var OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin');
  1. 在plugins节点下新增插件:
 new OptimizeCssAssetsPlugin() // 压缩CSS文件的插件

相关文章

  1. Sass 基础教程
  2. webpack-dev-server
  3. You have not accepted the license agreements of the following

3.移动App第3天

ReactJS简介

  • React 起源于 Facebook 的内部项目,因为该公司对市场上所有 JavaScript MVC 框架,都不满意,就决定自己写一套,用来架设 Instagram 的网站。做出来以后,发现这套东西很好用,就在2013年5月开源了
  • 由于 React 的设计思想极其独特,属于革命性创新,性能出众,代码逻辑却非常简单。所以,越来越多的人开始关注和使用,认为它可能是将来 Web 开发的主流工具。
  • library
  • Framework

前端三大主流框架

  • Angular.js:出来最早的前端框架,学习曲线比较陡,NG1学起来比较麻烦,NG2开始,进行了一系列的改革,也开始启用组件化了;在NG中,也支持使用TS(TypeScript)进行编程;
  • Vue.js:最火的一门前端框架,它是中国人开发的,对我我们来说,文档要友好一些;
  • React.js:最流行的一门框架,因为它的设计很优秀;
  • windowsPhone 7 7.5 8 10

React与vue.js的对比

组件化方面

  1. 什么是模块化:从 代码 的角度,去分析问题,把我们编程时候的业务逻辑,分割到不同的模块中来进行开发,这样能够方便代码的重用
  2. 什么是组件化:从 UI 的角度,去分析问题,把一个页面,拆分为一些互不相干的小组件,随着我们项目的开发,我们手里的组件会越来越多,最后,我们如果要实现一个页面,可能直接把现有的组件拿过来进行拼接,就能快速得到一个完整的页面, 这样方便了UI元素的重用组件是元素的集合体
  3. 组件化的好处:
  4. Vue是如何实现组件化的:.vue 组件模板文件,浏览器不识别这样的.vue文件,所以,在运行前,会把 .vue 预先编译成真正的组件;
  • template: UI结构
  • script: 业务逻辑和数据
  • style: UI的样式
  1. React如何实现组件化:在React中实现组件化的时候,根本没有 像 .vue 这样的模板文件,而是,直接使用JS代码的形式,去创建任何你想要的组件;
  • React中的组件,都是直接在 js 文件中定义的;
  • React的组件,并没有把一个组件 拆分为 三部分(结构、样式、业务逻辑),而是全部使用JS来实现一个组件的;(也就是说:结构、样式、业务逻辑是混合在JS里面一起编写出来的)

开发团队方面

  • React是由FaceBook前端官方团队进行维护和更新的;因此,React的维护开发团队,技术实力比较雄厚;
  • Vue:第一版,主要是有作者 尤雨溪 专门进行维护的,当 Vue更新到 2.x 版本后,也有了一个小团队进行相关的维护和开发;

社区方面

  • 在社区方面,React由于诞生的较早,所以社区比较强大,一些常见的问题、坑、最优解决方案,文档、博客在社区中都是可以很方便就能找到的;
  • Vue是近两年才诞生开源出来的,所以,它的社区相对于React来说,要小巧一些,所以,可能有的一些坑,没人踩过;

移动APP开发体验方面

  • Vue,结合 Weex 这门技术,提供了 迁移到 移动端App开发的体验(Weex,目前只是一个 小的玩具, 并没有很成功的 大案例;)
  • React,结合 ReactNative,也提供了无缝迁移到 移动App的开发体验(RN用的最多,也是最火最流行的);

为什么要学习React

  1. 设计很优秀,是基于组件化的,方便我们UI代码的重用;
  2. 开发团队实力强悍,不必担心短更的情况;
  3. 社区强大,很多问题都能找到对应的解决方案;
  4. 提供了无缝转到 ReactNative 上的开发体验,让我们技术能力得到了拓展;增强了我们的核心竞争力

React中几个核心的概念

虚拟DOM(Virtual Document Object Model)

  • DOM的本质是什么:就是用JS表示的UI元素
  • DOM和虚拟DOM的区别:
    • DOM是由浏览器中的JS提供功能,所以我们只能人为的使用 浏览器提供的固定的API来操作DOM对象;
    • 虚拟DOM:并不是由浏览器提供的,而是我们程序员手动模拟实现的,类似于浏览器中的DOM,但是有着本质的区别;
  • 为什么要实现虚拟DOM:
  • 什么是React中的虚拟DOM:
  • 虚拟DOM的目的:

虚拟DOM引入图片.png

Diff算法

  • tree diff:新旧DOM树,逐层对比的方式,就叫做 tree diff,每当我们从前到后,把所有层的节点对比完后,必然能够找到那些 需要被更新的元素;
  • component diff:在对比每一层的时候,组件之间的对比,叫做 component diff;当对比组件的时候,如果两个组件的类型相同,则暂时认为这个组件不需要被更新,如果组件的类型不同,则立即将旧组件移除,新建一个组件,替换到被移除的位置;
  • element diff:在组件中,每个元素之间也要进行对比,那么,元素级别的对比,叫做 element diff;
  • key:key这个属性,可以把 页面上的 DOM节点 和 虚拟DOM中的对象,做一层关联关系;

Diff.png

React项目的创建

  1. 运行 cnpm i react react-dom -S 安装包
  2. 在项目中导入两个相关的包:
// 1. 在 React 学习中,需要安装 两个包 react  react-dom
// 1.1 react 这个包,是专门用来创建React组件、组件生命周期等这些东西的;
// 1.2 react-dom 里面主要封装了和 DOM 操作相关的包,比如,要把 组件渲染到页面上
import React from 'react'
import ReactDOM from 'react-dom'
  1. 使用JS的创建虚拟DOM节点:
    // 2. 在 react 中,如要要创建 DOM 元素了,只能使用 React 提供的 JS API 来创建,不能【直接】像 Vue 中那样,手写 HTML 元素
    // React.createElement() 方法,用于创建 虚拟DOM 对象,它接收 3个及以上的参数
    // 参数1: 是个字符串类型的参数,表示要创建的元素类型
    // 参数2: 是一个属性对象,表示 创建的这个元素上,有哪些属性
    // 参数3: 从第三个参数的位置开始,后面可以放好多的虚拟DOM对象,这写参数,表示当前元素的子节点
    // <div title="this is a div" id="mydiv">这是一个div</div>

    var myH1 = React.createElement('h1', null, '这是一个大大的H1')

    var myDiv = React.createElement('div', { title: 'this is a div', id: 'mydiv' }, '这是一个div', myH1)
  1. 使用 ReactDOM 把元素渲染到页面指定的容器中:
    // ReactDOM.render('要渲染的虚拟DOM元素', '要渲染到页面上的哪个位置中')
    // 注意: ReactDOM.render() 方法的第二个参数,和vue不一样,不接受 "#app" 这样的字符串,而是需要传递一个 原生的 DOM 对象
    ReactDOM.render(myDiv, document.getElementById('app'))

JSX语法

  1. 如要要使用 JSX 语法,必须先运行 cnpm i babel-preset-react -D,然后再 .babelrc 中添加 语法配置;
  2. JSX语法的本质:还是以 React.createElement 的形式来实现的,并没有直接把 用户写的 HTML代码,渲染到页面上;
  3. 如果要在 JSX 语法内部,书写 JS 代码了,那么,所有的JS代码,必须写到 {} 内部;
  4. 当 编译引擎,在编译JSX代码的时候,如果遇到了<那么就把它当作 HTML代码去编译,如果遇到了 {} 就把 花括号内部的代码当作 普通JS代码去编译;
  5. 在{}内部,可以写任何符合JS规范的代码;
  6. 在JSX中,如果要为元素添加class属性了,那么,必须写成className,因为 class在ES6中是一个关键字;和class类似,label标签的 for 属性需要替换为 htmlFor.
  7. 在JSX创建DOM的时候,所有的节点,必须有唯一的根元素进行包裹;
  8. 如果要写注释了,注释必须放到 {} 内部

React中:第一种创建组件的方式

第一种基本组件的创建方式

父组件向子组件传递数据

属性扩散

将组件封装到单独的文件中

React中:第二种创建组件的方式

了解ES6中class关键字的使用

基于class关键字创建组件

  • 使用 class 关键字来创建组件
class Person extends React.Component{
    // 通过报错提示得知:在class创建的组件中,必须定义一个render函数
    render(){
        // 在render函数中,必须返回一个null或者符合规范的虚拟DOM元素
        return <div>
            <h1>这是用 class 关键字创建的组件!</h1>
        </div>;
    }
}

两种创建组件方式的对比

  1. 用构造函数创建出来的组件:专业的名字叫做“无状态组件”
  2. 用class关键字创建出来的组件:专业的名字叫做“有状态组件”

用构造函数创建出来的组件,和用class创建出来的组件,这两种不同的组件之间的本质区别就是:有无state属性!!!
有状态组件和无状态组件之间的本质区别就是:有无state属性!

一个小案例,巩固有状态组件和无状态组件的使用

通过for循环生成多个组件

  1. 数据:
CommentList = [
    { user: '张三', content: '哈哈,沙发' },
    { user: '张三2', content: '哈哈,板凳' },
    { user: '张三3', content: '哈哈,凉席' },
    { user: '张三4', content: '哈哈,砖头' },
    { user: '张三5', content: '哈哈,楼下山炮' }
]

style样式

总结

理解React中虚拟DOM的概念
理解React中三种Diff算法的概念
使用JS中createElement的方式创建虚拟DOM
使用ReactDOM.render方法
使用JSX语法并理解其本质
掌握创建组件的两种方式
理解有状态组件和无状态组件的本质区别
理解props和state的区别

相关文章

4.移动App第4天

组件的生命周期

  • 概念:组件从创建、到运行、再到销毁,这期间总是伴随着各种各样的事件,那么,这些事件统称为 组件的生命周期函数;
  • 组件生命周期分为三部分:
    • 组件创建阶段:生命周期函数,有一个显著的特点:组件一生只执行一次;

    • 组件运行阶段:这些函数,也有显著的特点: 一生会根据属性props 和 状态 state 的改变,有选择性的触发0次或多次;

    • 组件销毁阶段:这些函数,也有显著的特点:一生只执行一次;

vue中的生命周期图
React Native 中组件的生命周期

React中组件的生命周期.png

defaultProps

在组件创建之前,会先初始化默认的props属性,这是全局调用一次,严格地来说,这不是组件的生命周期的一部分。在组件被创建并加载候,首先调用 constructor 构造器中的 this.state = {},来初始化组件的状态。

React生命周期的回调函数总结成表格如下:

React生命周期表格.png

组件生命周期的执行顺序:

  • Mounting:
  • constructor()
  • componentWillMount()
  • render()
  • componentDidMount()
  • Updating:
  • componentWillReceiveProps(nextProps)
  • shouldComponentUpdate(nextProps, nextState)
  • componentWillUpdate(nextProps, nextState)
  • render()
  • componentDidUpdate(prevProps, prevState)
  • Unmounting:
  • componentWillUnmount()

通过Counter计数器的小案例 - 了解生命周期函数

  1. 给组件设置默认属性:
  2. 给属性进行类型校验,需要先运行cnpm i prop-types --save

组件初始化时生命周期事件总结

  1. componentWillMount:
  2. render:
  3. componentDidMount:
  4. 注意:在render函数中,不能调用setState()方法

通过原生的方式获取元素并绑定事件

React中使用ref属性获取DOM元素引用

使用React中的事件,绑定count自增

组件运行中事件的对比

  1. shouldComponentUpdate:
  2. componentWillUpdate:
  3. render:
  4. componentDidUpdate:

绑定this并传参的三种方式

  1. 在事件中绑定this并传参:
    <input type="button" value="在事件中绑定this并传参" onClick={this.handleMsg1.bind(this, '🍕', '🍟')} />

    // 在事件中绑定this并传参
    handleMsg1(arg1, arg2) {
        console.log(this);
        // 此时this是个null
        this.setState({
            msg: '在事件中绑定this并传参:' + arg1 + arg2
        });
    }
  1. 在构造函数中绑定this并传参:
    // 修改构造函数中的代码:
    this.handleMsg2 = this.handleMsg2.bind(this, '🚗', '🚚');

    <input type="button" value="在构造函数中绑定this并传参" onClick={this.handleMsg2} />

    // 在构造函数中绑定this并传参
    handleMsg2(arg1, arg2) {
        this.setState({
            msg: '在构造函数中绑定this并传参:' + arg1 + arg2
        });
    }
  1. 用箭头函数绑定this并传参:
    <input type="button" value="用箭头函数绑定this并传参" onClick={() => { this.handleMsg3('👩', '👰') }} />

    // 用箭头函数绑定this并传参
        handleMsg3(arg1, arg2) {
            this.setState({
                msg: '用箭头函数绑定this并传参:' + arg1 + arg2
            });
        }

绑定文本框与state中的值

  1. 在Vue.js中,默认可以通过v-model指令,将表单控件和我们的data上面的属性进行双向数据绑定,数据变化和页面之间的变化是同步的!
  2. 在React.js中,默认没有提供双向数据绑定这一功能,默认的,只能把state之上的数据同步到界面的控件上,但是不能默认实现把界面上数据的改变,同步到state之上,需要程序员手动调用相关的事件,来进行逆向的数据传输!
  3. 绑定文本框和state的值:
    {/*只要将value属性,和state上的状态进行绑定,那么,这个表单元素就变成了受控表单元素,这时候,如果没有调用相关的事件,是无法手动修改表单元素中的值的*/}
    <input style={{ width: '100%' }} ref="txt" type="text" value={this.state.msg} onChange={this.handleTextChange} />

    // 这是文本框内容改变时候的处理函数
    handleTextChange = () => {
        this.setState({
            msg: this.refs.txt.value
        });
    }
  1. 注意setState的一个问题
// 保存最新的state状态值,在保存的时候,是异步地进行保存的,所以,如果想要获取最新的,刚刚保存的那个状态,需要通过回掉函数的形式去获取最新state
this.setState({
    msg: this.refs.txt.value
    // msg: e.target.value
}, function () {
    // 获取最新的state状态值
    console.log(this.state.msg);
});

发表评论案例

扩展

context特性

记住一串单词组合getChildContextTypes
前3个、后3个、后两个
一个方法、两个静态属性

相关文章

类型校验
Animation Add-Ons
移动端 关于 键盘将input 框 顶上去的解决思路—个人见解

5.移动App第5天-豆瓣电影

Node.js设置跨域


app.use('*', function (req, res, next) {

  // 设置请求头为允许跨域

    res.header("Access-Control-Allow-Origin", "*");

    // 设置服务器支持的所有头信息字段

    res.header("Access-Control-Allow-Headers", "Content-Type,Content-Length, Authorization, Accept,X-Requested-With");

    // 设置服务器支持的所有跨域请求的方法

    res.header("Access-Control-Allow-Methods", "POST,GET");

    // next()方法表示进入下一个路由

    next();

});

Promise规范

  1. 定义:就是一个异步的代码规范;

  2. 好处:

  • 更好的帮我们解决回调地狱问题

  • 能帮我们很好的实现代码的复用

基于Promise规范的fetch API的使用

项目结构搭建和布局

  1. 运行npm install antd --save安装ant design

  2. 导入相关组件:


import { DatePicker } from 'antd';

  1. 导入样式:

import 'antd/dist/antd.css';

实现ANT组件的按需加载

  1. 运行cnpm i babel-plugin-import --save-dev

  2. 修改.babelrc文件:


{

    "presets":["es2015", "stage-0", "react"],

    "plugins":[

        "transform-runtime",

        ["import", { "libraryName": "antd", "style": "css" }]

        ]

}

  1. 然后只需从 antd 引入模块即可,无需单独引入样式。等同于下面手动引入的方式。

使用react-router-dom实现路由跳转

  • HashRouter:是一个路由的跟容器,一个应用程序中,一般只需要唯一的一个HashRouter容器即可!将来,所有的Route和Link都要在HashRouter中进行使用
  • 注意:HashRouter中,只能有唯一的一个子元素
  • Link:是相当于超链接一般的存在;点击Link,跳转到相应的路由页面!负责进行路由地址的切换!

  • Route:是路由匹配规则,当路由地址发生切换的时候,就会来匹配这些定义好的Route规则,如果有能匹配到的路由规则,那么,就会展示当前路由规则所对应的页面!

  • Route:除了是一个匹配规则之外,还是一个占位符,将来,此Route所匹配到的组件页面,将会展示到Route所在的这个位置!


// 其中path指定了路由匹配规则,component指定了当前规则所对应的组件

<Route path="" component={}></Route>

  • 注意:react-router中的路由匹配,是进行模糊匹配的!可以通过Route身上的exact属性,来表示当前的Route是进行精确匹配的

  • 可以使用Redirect实现路由重定向


    // 导入路由组件

    import {Route, Link, Redirect} from 'react-router-dom'



    <Redirect to="/movie/in_theaters"></Redirect>

this.prop和Route的关系【重要】

获取到参数之后,从服务器获取电影数据

使用Node服务器转接豆瓣API

渲染电影列表

相关文章

6.React第6天

RN学习说明

  1. ReactNative是基于React这门框架的语法来进行开发的;
  2. RN中,提供了 移动端 专用的一些组件,这时候,我们在网页中使用的一些 元素,div, p, img 都不能用了,只能使用RN固有的组件;
  3. 最终,开发出来的项目,是要运行到手机上的,那么,如何把一个 RN 的项目,完整的发布到手机上去运行呢,这里,需要结合 安卓的 签名打包步骤,并使用 RN 提供的打包命令,进行完整 apk 文件的发布;最终发布出来的就是 Release 版本的项目,可以上传到应用商店;

配置ReactNative基本开发环境

搭建基本的开发环境 - 英文官网

搭建基本的开发环境 - 中文
这两篇文档对比着进行参考,进行相关的安装;

手机的相关配置

  1. 使用数据线,把手机链接到电脑上;
  2. 运行 adb devices 的命令,这个命令,是安卓开发环境提供的;
  3. 需要先开启手机的开发者模式
  4. 如果开启开发者模式之后,还是看不到设备,则尝试安装 豌豆荚 这样的工具,让这些工具帮助你在电脑上安装手机的驱动;

搭建RN的项目

  1. 运行react-native init 项目名称来初始化一个react native项目;

01.项目初始化完毕之后截图并说明.png

  1. 打包运行项目,把打包好的项目部署到手机中!
  • 确保手机已经正确的链接到了当前电脑上,同时手机开启了开发者调试模式;可以使用adb devices来查看当前链接到电脑上的手机设备列表!
  • 当确认手机正确链接到电脑上之后,可以运行react-native run-android来打包当前项目,并把打包好的项目以调试的模式安装到手机中!
  • 打包完成之后的截图

02.打包完成之后的截图.png

  • React Package窗口的作用

03.React Package窗口的作用.png

04.React  Packager打包编译代码截图.png

  • 当第一打包编译项目部署到手机上之后 - 如何设置开发服务器的地址

05.当第一打包编译项目部署到手机上之后 - 如何设置开发服务器的地址.png

项目结构介绍以及一些注意事项

使用样式

##修改项目首屏页面

基本组件的使用介绍

  • View:
  • Text:
  • TextInput:
  • Image:
  • Button:
  • ActivityIndicator:
  • ScrollView:这是一个列表滚动的组件
  • ListView:也是一个列表滚动的组件,但是,这个组件已经过时了,官方推荐使用 FlatList 来代替它

判断组件是否被卸载

if (this._reactInternalInstance){
  // 组件没有被卸载
}

配置Tab栏

配置Tab栏的图标

注意:使用图标,需要使用 Android SDK Manager 安装 Android SDK Build-tools 26.0.1 并接收其 license;

案例:豆瓣电影列表

  • 电影列表数据:https://api.douban.com/v2/movie/in_theaters
  • 电影详细数据:https://api.douban.com/v2/movie/subject/26309788

安装路由

  1. 运行npm i react-native-router-flux --save
  2. 路由官网:https://github.com/aksonov/react-native-router-flux
  3. 路由相关配置:https://github.com/aksonov/react-native-router-flux/blob/master/docs/API.md
  4. 路由简单的DEMO:https://github.com/aksonov/react-native-router-flux/blob/v3/docs/MINI_TUTORIAL.md

路由的一些基本使用方法

配置首页的轮播图

  1. 轮播图官网:https://github.com/leecade/react-native-swiper?utm_source=tuicool&utm_medium=referral
  2. 运行npm i react-native-swiper --save安装轮播图组件
  3. 导入轮播图组件import Swiper from 'react-native-swiper';
  4. 其中,在Swiper身上,showsPagination={false}是用来控制页码的;showsButtons={false}是用来控制左右箭头显示与隐藏;height={160}是用来控制轮播图区域的高度的!
  5. 设置轮播图的样式:
var styles = StyleSheet.create({
    wrapper: {},
    slide1: {
        flex: 1,
        justifyContent: 'center',
        alignItems: 'center',
        backgroundColor: '#9DD6EB',
    },
    slide2: {
        flex: 1,
        justifyContent: 'center',
        alignItems: 'center',
        backgroundColor: '#97CAE5',
    },
    slide3: {
        flex: 1,
        justifyContent: 'center',
        alignItems: 'center',
        backgroundColor: '#92BBD9',
    },
    image:{
        width:'100%',
        height:'100%'
    }
})
  1. 将组件的代码结构引入到页面上:
<Swiper style={styles.wrapper} showsButtons={true} height={160} autoplay={true}>
                <View style={styles.slide1}>
                    <Image source={{uri:'http://www.itcast.cn/images/slidead/BEIJING/2017410109413000.jpg'}} style={styles.image}></Image>
                </View>
                <View style={styles.slide2}>
                    <Image source={{uri:'http://www.itcast.cn/images/slidead/BEIJING/2017440109442800.jpg'}} style={styles.image}></Image>
                </View>
                <View style={styles.slide3}>
                    <Image source={{uri:'http://www.itcast.cn/images/slidead/BEIJING/2017441409442800.jpg'}} style={styles.image}></Image>
                </View>
            </Swiper>

首页轮播图片URL地址:

  • 图片地址1:http://www.itcast.cn/images/slidead/BEIJING/2017410109413000.jpg
  • 图片地址2:http://www.itcast.cn/images/slidead/BEIJING/2017440109442800.jpg
  • 图片地址3:http://www.itcast.cn/images/slidead/BEIJING/2017441409442800.jpg

渲染电影列表数据

渲染电影详情页面

调用摄像头拍照

react-native-image-picker的github官网
react native 之 react-native-image-picke的详细使用图解

  1. 运行npm install react-native-image-picker@latest --save安装到项目运行依赖,此时调试可能会报错,如果报错,需要使用下面的步骤解决:
  • 先删除node_modules文件夹
  • 运行npm i
  • 运行npm start --reset-cache
  1. 运行react-native link自动注册相关的组件到原生配置中
  2. 打开项目中的android->app->src->main->AndroidManifest.xml文件,在第8行添加如下配置:
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
  1. 打开项目中的android->app->src->main->java->com->当前项目名称文件夹->MainActivity.java文件,修改配置如下:
    package com.native_camera;
    import com.facebook.react.ReactActivity;
    
    // 1. 添加以下两行:
    import com.imagepicker.permissions.OnImagePickerPermissionsCallback; // <- add this import
    import com.facebook.react.modules.core.PermissionListener; // <- add this import
    
    public class MainActivity extends ReactActivity {
        // 2. 添加如下一行:
        private PermissionListener listener; // <- add this attribute
    
        /**
         * Returns the name of the main component registered from JavaScript.
         * This is used to schedule rendering of the component.
         */
        @Override
        protected String getMainComponentName() {
            return "native_camera";
        }
    }
    
  2. 在项目中添加如下代码:
    // 第1步:
    import {View, Button, Image} from 'react-native'
    import ImagePicker from 'react-native-image-picker'
    var photoOptions = {
      //底部弹出框选项
      title: '请选择',
      cancelButtonTitle: '取消',
      takePhotoButtonTitle: '拍照',
      chooseFromLibraryButtonTitle: '选择相册',
      quality: 0.75,
      allowsEditing: true,
      noData: false,
      storageOptions: {
        skipBackup: true,
        path: 'images'
      }
    }
    
    // 第2步:
    constructor(props) {
    super(props);
        this.state = {
          imgURL: ''
        }
      }
    

// 第3步:
<Image source={{ uri: this.state.imgURL }} style={{ width: 200, height: 200 }}>

// 第4步:
cameraAction = () => {
ImagePicker.showImagePicker(photoOptions, (response) => {
  console.log('response' + response);
  if (response.didCancel) {
    return
  }
  this.setState({
    imgURL: response.uri
  });
})

}
```
6. 一定要退出之前调试的App,并重新运行react-native run-android进行打包部署;这次打包期间会下载一些jar的包,需要耐心等待!

签名打包发布Release版本的apk安装包

  • 请参考以下两篇文章:

如何发布一个apk

  1. 先保证自己正确配置了所有的 RN 环境
  2. 在 cmd 命令行中,运行这一句话keytool -genkey -v -keystore my-release-key2.keystore -alias my-key-alias2 -keyalg RSA -keysize 2048 -validity 10000
  • 其中: my-release-key.keystore 表示你一会儿要生成的那个 签名文件的 名称【很重要,包找个小本本记下来】
  • -alias 后面的东西,也很重要,需要找个小本本记下来,这个名称可以根据自己的需求改动my-key-alias
  • 当运行找个命令的时候,需要输入一系列的参数,找个口令的密码,【一定要找个小本本记下来】
  1. 当生成了签名之后,这个签名,默认保存到了自己的用户目录下C:\Users\liulongbin\my-release-key2.keystore
  2. 将你的签名证书copy到 android/app目录下。
  3. 编辑 android -> gradle.properties文件,在最后,添加如下代码:
MYAPP_RELEASE_STORE_FILE=your keystore filename
MYAPP_RELEASE_KEY_ALIAS=your keystore alias
MYAPP_RELEASE_STORE_PASSWORD=*****
MYAPP_RELEASE_KEY_PASSWORD=*****
  1. 编辑 android/app/build.gradle文件添加如下代码:
...
android {
    ...
    defaultConfig { ... }
    + signingConfigs {
    +    release {
    +        storeFile file(MYAPP_RELEASE_STORE_FILE)
    +        storePassword MYAPP_RELEASE_STORE_PASSWORD
    +        keyAlias MYAPP_RELEASE_KEY_ALIAS
    +        keyPassword MYAPP_RELEASE_KEY_PASSWORD
    +    }
    +}
    buildTypes {
        release {
            ...
    +        signingConfig signingConfigs.release
        }
    }
}
...
  1. 进入项目根目录下的android文件夹,在当前目录打开终端,然后输入./gradlew assembleRelease开始发布APK的Release版;
  2. 当发行完毕后,进入自己项目的android\app\build\outputs\apk目录中,找到app-release.apk,这就是我们发布完毕之后的完整安装包;就可以上传到各大应用商店供用户使用啦;

注意:请记得妥善地保管好你的密钥库文件,不要上传到版本库或者其它的地方。

相关文章

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!