vue,react,angular三大web前端流行框架简单对比

2018/11/23 13:00
阅读数 27

常用的到的网站

vue学习库:

https://github.com/vuejs/awesome-vue#carousel

(json数据的格式化,提高本地测试的效率)

json在线编辑:

http://www.bejson.com/
http://www.kjson.com/

//提供fake的数据:
http://jsonplaceholder.typicode.com/users

/posts 100 posts
/comments 500 comments
/albums 100 albums
/photos 5000 photos
/todos 200 todos
/users 10 users

https://github.com/gdi2290/awesome-angular

PC:
https://material.angular.cn/
https://ng.ant.design/docs/introduce/zh
Mobile:
ionic

ionicframework.com
ionicframework.com/docs
ionicons.com

React:
https://reactjs.org/ 官网
https://github.com/enaqx/awesome-react 基于React的第三方库

Flutter Google所推出的一个构建移动端原生app的框架 flutter.io

https://github.com/jondot/awesome-react-native#ui 基于ReactNative的第三方的工具库

封装:提到代码的复用率、提高开发效率、方便代码的维护和升级


零、回顾
VueJS:渐进式的js框架
vue核心库 vueRouter vuex
vue插件 plugin vue.use()

Vue生态系统?
vuejs+vueRouter+vuex+Element/Mint+weex(原生开发)+vux(移动端的ui组件库)

①Vue基础语法 指令
{{expression}}
v-for v-if v-else
v-on @
v-bind :
v-model
②Vue 路由模块(建立组件和url之间的映射关系)
路由基本使用:
引入对应的模块
router-view
完成组件的创建和引入
配置路由词典(路由对象构成的数组)
导航:
this.$router.push()
this.$router.forward()
this.$router.back()
this.$router.go(n)
<router-link to=""></router-link>
传参:
明确发送方和接收方

配置接收方的路由地址 /detail/:id this.$route.params

发送
this.$router.push('/detail/1')
路由嵌套:
mail
步骤1:mail指定一个router-view
步骤2:在mail对应的路由对象配置子路由
{
path:'/mail',
component:Mail,
children:[

]
}
路由守卫
③Vue 网络请求
axios.get/post/**().then()
④Vue 组件间通信
props down (父--》子)
events up (子--》父)
bus
ref
$parent
⑤vuex
state
getters
mutations
actions
modules


一、Angular概述
what
One framework.Mobile & desktop.
是一个js的框架,实现移动端和pc端的开发
Angular 是一个用 HTML 和 TypeScript 构建客户端应用的平台与框架。 Angular 本身使用 TypeScript 写成的。它将核心功能和可选功能作为一组 TypeScript 库进行实现,你可以把它们导入你的应用中。
when
SPA(single page application)
why
技术团队Google

typescript是一种强类型检查机制的语言

angular涉及到的内容很多,减少开发者的开发压力
how
组件定义视图。视图是一组可见的屏幕元素,Angular 可以根据你的程序逻辑和数据来选择和修改它们。 每个应用都至少有一个根组件。

组件使用服务。服务会提供那些与视图不直接相关的功能。服务提供商可以作为依赖被注入到组件中, 这能让你的代码更加模块化、可复用,而且高效。
(command line interface)
Angular CLI是一个命令行界面工具,它可以创建项目、添加文件以及执行一大堆开发任务,比如测试、打包和发布。
npm i -g @angular/cli 全局安装cli工具
ng new my-app 创建一个叫做my-app的项目
cd my-app 进入到当前目录下的my-app目录中
ng serve 启动开发服务器

准备ng的使用环境:
①拷贝.bin目录
C:\xampp\htdocs\framework\ng\myngapp\node_modules\.bin
②计算机,鼠标右键点击,选中属性
③选中高级系统设置
④选中环境变量
⑤系统变量中的path,编辑
⑥新建,粘贴

npm start 启动流程:
执行根模块 app.module.ts,通过bootstrap属性指定了启动的根组件 app.component.ts
在根组件中 有一个模块 app.component.html
index.html-->根组件中 通过selector属性所指定的app-root

启动开发服务器
npm start

二、组件的创建和调用
组件:可被反复使用的,带有特定功能的视图

Vue组件:
//全局组件
Vue.component('',{
template:``,
components:{
//局部组件
'my-test':{
}
}
})

1、创建
ng generate component demo01
ng g component demo02
2、用
src/app/app.component.html
<app-demo01></app-demo01>


组件本身的注意事项:
①在通过cli去创建组件时,会在src目录下创建一个文件夹,该文件夹创建4个文件
②自动的app.module.ts帮助注册这个组件

使用注意:
①npm start 启动开发服务器
②ng node不识别
重装nodejs
③ng的环境变量在cmd.exe是可以识别的,但是在powershell中无法解析
统一使用cmd.exe
windows+R-->cmd-->cd 工程的目录

三、Angular基本语法
1、装饰器、元数据(了解)
装饰器(decorator) 是用来描述当前这个类
元数据(metaData) 使用来告诉Angular框架如何来处理当前这个类

@Component
selector 作为标签用的名称(选择器)
templateUrl 模板内容
styleUrls 当前引用的样式类文件
@NgModule
bootstrap
declarations
imports
providers

2、{{}}

3、常见内部指令(重点)
3.1 循环
<any *ngFor="let tmp of list"></any>
<any *ngFor="let tmp of list;let myIndex=index"></any>

3.2 条件
<any *ngIf="expression"></any>

注意事项:
①*ngFor和*ngIf不能同时使用在一个标签中,借助于ng-containter


3.3 属性绑定
<any [属性]="expression"></any>

3.4 事件绑定
<any (事件名称)="事件处理函数()"></any>

3.5 双向数据绑定(根模块依赖于FormsModule)
基本用法:
<any [(ngModel)]="变量"></any>

检测模型数据的变化:
<any [(ngModel)]="变量" (ngModelChange)=""></any>

3.6 样式绑定 样式类的绑定
:style="{fontSize:mySize}"
:class="{myClass:expression}"

[ngStyle]="{color:myColor}"
[ngClass]="{myClass:true/false}"


4、创建自定义指令(难点)
复习:
Vue.directive('test',{

})

指令: 获取元素,扩展功能
组件的本质 就是带有模板的指令

4.1 封装一个指令类
ng g component **
ng g directive test

4.2 调用一个指令类
调用之前 在根模块中的declarations数组中先声明!

进阶知识:
①如何得到调用当前指令的元素?
ElementRef
步骤1:引入
import {ElementRef} from '@angular/core'
步骤2:实例化
constructor(private ef:ElementRef){}
步骤3:获取元素
this.ef.nativeElement
②如何获取调用指令时 所传递的参数
import {Input,OnInit} from '@angular/core'

export class TestDirective implements OnInit{
@Input() AppTest=""

ngOnInit(){
//this.AppTest
}
}

目标:
<h2 **="red"></h2>
接收到值,将当前调用指定的元素的背景色 设置为和参数相同的值

步骤1:完成指令的创建 和调用
ng g directive change-bg

步骤2:传参、接收
Input OnInit
步骤3: 获取调用指令的元素
ElementRef

5、常见内部管道(过滤器)
回顾:
Vue.filter('',(arg1)=>{return 处理后的结果})

<any>{{expression | myFilter(1,2)}}</any>

管道:目的是将程序原始数据,进行筛选、过滤、格式化的处理,本质:有参数有返回值的方法

用法:
<any>
{{expression | myPipe:arg1:arg2}}
</any>
注意事项:
管道在调用时 所支持的参数的个数和类型

具体管道:
①currency (将一个数字进行货币的格式化)
<any>{{123 | currency:'CNY'}}</any>
②percent (将数字转换为百分比的形式)
<any>{{0.31223432 | percent:'2.3-4'}}</any>
③uppercase/lowercase(大小写的转换)
<any>{{"John"|uppercase/lowercase}}</any>
④number(将数字进行格式化处理)
<any>{{31.223432 | number:'2.3-4'}}</any>
⑤slice
将数组或者字符串进行截取的处理
<any>{{expression | slice:5:10}}</any>

6、创建自定义管道
ng g pipe sex

import {Pipe,PipeTransform} from '@angular/core'

@Pipe({
name:'myCurrrency'
})

export class MyCurrencyPipe implements PipeTransform{
transform(value:any,args?:any){
//获取value(竖杠前边表达式执行的结果)
//args(冒号后边的参数)
//对数据和参数进行处理
//返回处理后的结果
}
}

调用之前:
在app.module.ts中declarations注册下当前的管道类
调用:
用法和内置的管道用法是一样的!

7、完成服务类的创建和使用(重点)
服务类:在Angular中 建议大家将常用的功能封装在服务类中 ,比如像网络通讯、数据某些处理、日志处理。。


7.1 创建
ng g service my-log

关键词:
@Injectable(
{
providedIn:'root'
}
)

7.2 调用
组件是服务类的最大消费者

import {MyLogService} from '../my-log.service'

constructor(private myService:MyLogService)

this.myService.**

7.3 DependencyInjection(依赖注入)
依赖注入(DI)是用来创建对象及其依赖的其它对象的一种方式

在创建要用到的类的对象时,依赖无需理会,将注意力放在要关心的对应的类。

四、组件间通信(重点)
回顾Vue:
props down:
myName ='zhangsan'
<son :sonName='myName'></son>
<son sonName='zhangsan'></son>

Vue.component('son',{
props:['sonName']
//this.sonName
})
events up:
父(接收方):
rcvMsg(msg){}
<son @myEvent="rcvMsg"></son>
<son @myEvent="rcvMsg($event)"></son>
子(发送方): this.$emit('myEvent',123)
bus:
var bus = new Vue();
//绑定
bus.$on('',(msg)=>{})
//触发
bus.$emit('',123)

1 props down(父--data--》子)
在调用子组件时,借助于属性给子组件进行传值
步骤1:传值
loginValue = true;
<son [isLogin]='loginValue'></son>
<son isLogin='true'></son>
步骤2:接收
到子组件中,准备接收:
import {Input} from '@angular/core'
@Input() isLogin=false;
this.isLogin

练习:(:- 16:45)
demo11-parent(只调用子组件)
demo11-son(只有一个无序列表)
需求:在根组件中 调用demo11-parent组件类;在demo11-parent中调用demo11-son组件
步骤1:完成组件类的常见和调用
步骤2:在demo11-parent组件中 声明一个数组list=[100,200,300];调用demo11-son时通过自定义属性myList将数组传递子组件
步骤3:demo11-son接收到属性myList对应的值;在无序列表中 将接收到的数组遍历创建多个列表项


2 events up(子---data---》父)
步骤1:事件的绑定
rcvMsg(msg){
//msg就是子组件传来的数据
}
<son (rcvEvent)="rcvMsg($event)"></son>
步骤2:事件的触发
import {Output,EventEmitter} from '@angular/core'

@Output() rcvEvent = new EventEmitter()

this.rcvEvent.emit(123)


五、网络请求
默认的核心模块是不包含网络请求模块,
得让模块依赖于网络请求模块(HttpClientModule)

扩展:
设计原则:
高内聚低耦合

SRP单一责任原则(尽可能的将方法、模块进行划分,避免出现一个文件或者一个方法干了n多件事)
OCP开闭原则(对扩展开放 对修改关闭)

设计模式:
http://www.runoob.com/design-pattern/design-pattern-tutorial.html
工厂模式、单例模式、观察者模式、订阅者模式、MVC、MVVM、MVP


面试题:异步数据处理的方式?
ajax
promise
async/await
callback
rxjs:观察者模式、订阅者模式


步骤1:根模块依赖于HttpClientModule
app.module.ts
import {HttpClientModule} from '@angular/common/http'
@NgModule({
imports:[HttpClientModule]
})
步骤2:根模块的任何一个组件都可以调用网络请求
import {HttpClient} from '@angular/common/http'

constructor(private myHttp:HttpClient){}
//observable subscribe
this.myHttp.get("").subscribe((result)=>{
//result就是服务器端返回的数据
})

请求本地的服务:
①找到文件夹C:\xampp\htdocs\dd\xz
②通过编辑器打开该目录下的app.js
③修改允许跨域访问的域的端口:4200
④启动app.js :node app.js
⑤localhost:3000/index

网络请求注意事项:
①要请求的url地址不能写错
②参数的个数和类型不能出错
③如果前端确实没问题,检查后台返回的数据是否正确

六、路由模块 (RouterModule)
路由模块:建立组件和url之间的映射关系

可以将路由的配置单独的放在一个自定义模块中,让根模块依赖于自定义模块

1、基本用法
步骤1:创建一个自定义的模块(将路由的配置都统一的放在该文件)
①ng g module app-routing --flat --module=app
②app-routing.module.ts
import {RouterModule,Routes} from '@angular/router'

@NgModule({
exports:[RouterModule]
})

步骤2:指定一个盛放组件的容器
<router-outlet></router-outelt>

步骤3:创建要用到的组件
ng g component **

步骤4:配置和调用路由词典
app-routing.moduel.ts

const myRoutes:Routes = [
{path:'',component:**}
]

@NgModule({
imports:[
RouterModule.forRoot(myRoutes)
]
})


步骤5:测试
http://localhost:4200
http://localhost:4200/register


注意事项:
① 路由地址不能以/开头
② 路由地址的异常处理:path:'**'

练习:(:- 14:30)
需求:创建一个SPA(single page application),有两个组件:demo17-list(路由地址为空),demo17-detail(路由地址为detail)
步骤1:创建两个组件
步骤2:配置路由
步骤3:在demo17-list组件中,发起网路请求(HttpClient)
http://localhost:3000/products?kw=i5&pno=0
将服务端返回的数据的data对应的数组,显示在无序列表(列表项显示商品的title)
步骤4:在demo17-detail组件中,显示h2:这是详情页


2、导航
回顾:Vue
this.$router.push()
<router-link to="/detail">跳转到详情页</router-link>

Angular:
方案1:编程式导航
Router类中 navigateByUrl
import {Router} from '@angular/router'

constructor(private myRouter:Router){}

this.myRouter.navigateByUrl('目的地的路由地址')

方案2:
<any routerLink="oc"></any>


3、传参(跳转到某一个路由地址的时候,捎带了些数据)
回顾:Vue
步骤1:明确发送 接收
步骤2:发送
this.$router.push('/detail/123')
<router-link to='/detail/123'></router-link>
步骤3:配置路由地址
/detail --》 /detail/:id
this.$route.params.id

Angular:
①明确发送 接收方
②配置接受方的路由地址、接收
oc-->oc/:price
import {ActivatedRoute} from '@angular/router'

constructor(private myRoute:ActivatedRoute){}

this.myRoute.params.subscribe((result)=>{
//result.price
})

③发送
<h2 routerLink="oc/1000">去结算</h2>
this.myRouter.navigateByUrl('oc/1000')

要传递的参数是变量:
myPrice = 1000;
<h2 [routerLink]="'oc/'+myPrice">去结算</h2>
this.myRouter.navigateByUrl('oc/'+this.myPrice)

 

4、进阶知识--路由嵌套
在一个路由对象中,嵌套了其它的路由对象

A组件需要嵌套B、C
步骤1:给A组件指定一个盛放其他组件的容器
<router-outlet></router-outlet>
步骤2:配置子路由
{
path:'a',
component:AComponent,
children:[
{path:'b',component:BComponent},
{path:'c',component:CComponent}
]
}

需求:
demo20-login
demo21-mail
demo21-inbox
demo21-outbox

注意事项:
①单独来访问某个子路由,必须得携带父路由的地址
http://localhost:4200/mail/inbox

5、进阶知识--路由守卫
路由守卫:保护一个路由地址所对应的组件是否可以被访问
经常将路由守卫封装在一个服务类中

步骤1:创建一个服务类
ng g service my-guard
步骤2:让服务类实现了CanActiviate
import {CanActivate} from '@angular/router'

export class MyGuardService implements CanActivate{
//可以在该方法中,判断用户是否可以访问它要保护的页面,如果返回true意味着可以访问,否则是禁止访问
canActivate(){

return true/false;
}

}

步骤3:找到app-routing.module.ts
import {MyGuardService} from './my-guard.service'
{
path:'mail',
component:MailComponent,
canActivate:[MyGuardService]
}


七、Angular总结:
①组件:定义视图

②服务:将经常用到的数据和方法封装在一个类中;这能让你的代码更加模块化、可复用,而且高效

③依赖注入(DI): 服务的元数据提供了一些信息,Angular 要用这些信息来让组件可以通过使用该服务

④装饰器:用来描述当前这个类是一个什么样的类 @Component @NgModule @Pipe @Directive @Injectable

⑤模板:普通的 HTML 和指令与绑定标记(markup)组合起来

⑥指令:模板中的指令会提供程序逻辑
循环、条件判断。。。

⑦数据绑定:绑定标记会把你应用中的数据和 DOM 连接在一起。
①事件绑定让你的应用可以通过更新应用的数据来响应目标环境下的用户输入。
②属性绑定让你将从应用数据中计算出来的值插入到 HTML 中。
③双向数据绑定

⑧管道:转换要显示的值以增强用户体验


八、学习基于Angular的ui组件库
https://github.com/gdi2290/awesome-angular

PC:
https://material.angular.cn/
https://ng.ant.design/docs/introduce/zh
Mobile:
ionic

九、Ionic概述
ionic = angular + phonegap + 封装的组件和icon

what?
ionic用来构建移动端的应用程序的开源框架
why?
基于Angular、cordova
支持es6和ts
强大的cli支持
how?
npm install -g ionic
ionic start myApp tabs
cd myApp
ionic serve


//npm start
如果现在中心没有采用万寿路镜像的母盘:
有外网:npm install -g ionic
没外网:
①将ionic_cmd.zip拷贝到 C:\xampp\htdocs\framework\ng
②解压缩到当前的文件夹
③将C:\xampp\htdocs\framework\ng\node_mo
dules\.bin添加到环境变量

十、Ionic中Page类的创建和调用
创建:
ionic g page demo01

准备工作:
app.module.ts
import {Demo01Page} from '../pages/demo01/demo01'
@NgModule({
declaratons:[Demo01Page],
entryComponents:[Demo01Page]
})
调用:
app.component.ts
import {Demo01Page} from '../pages/demo01/demo01'
rootPage:any = Demo01Page;

练习:创建一个新的页面demo02-lianxi
让根组件默认显示这个页面;在这个页面类中 定义一个数组 list = [100,200,300];将数组循环遍历 在无序列表中创建多个列表项

十一、Ionic中常见组件 (重点)
1、button
ion-button
color: primary蓝色 secondary绿色 danger 红色 light浅灰色 dark黑色
(theme/variables.scss修改$colors变量)
outline 边框
clear 只保留按钮中的文本信息
block 占据父容器的宽度
large/small 大小
round 圆角效果
icon-left/right
<ion-icon name=""></ion-icon>

2、list
普通列表
<ion-list>
<ion-item>
</ion-item>
</ion-list>
icon列表
<ion-list>
<ion-item>
<ion-icon item-start/end></ion-icon>
</ion-item>
</ion-list>
avatar列表
<ion-list>
<ion-item>
<ion-avatar item-start/end>
<img/>
</ion-avatar>
</ion-item>
</ion-list>
thumbnail列表(重点)
<ion-list>
<ion-item>
<ion-thumbnail item-start/end>
<img/>
</ion-thumbnail>
</ion-item>
</ion-list>

进阶知识:
支持侧滑动的列表项
<ion-list>
<ion-item-sliding *ngFor="">
<ion-item></ion-item>
<ion-item-options>
<button></button>
</ion-item-options>
</ion-sliding>
</ion-list>

下拉刷新(重点)
步骤1:在ionContent第一个子元素的位置来调用ion-refresher
步骤2:绑定事件
<!--ios ios-small bubble circle crescent dots -->
<ion-refresher
(ionRefresh)="handleRefresh($event)">

<ion-refresher-content
pullingIcon="arrow-round-down"
pullingText="下拉刷新"

refreshingSpinner="bubbles"
refreshingText='正在刷新'>

</ion-refresher-content>
</ion-refresher>
步骤3:在事件处理函数做数据的操作,最后要结束刷新动作
handleRefresh(refresher){
//数据处理完成
refresher.complete()
}

上拉加载更多(重点)
步骤1:在ionContent最后一个子元素的位置来调用ion-infinite-scroll
步骤2:绑定事件 ionInfinite
<ion-infinite-scroll
(ionInfinite)="handleInfinite($event)">
<ion-infinite-scroll-content
loadingSpinner="bubbles" loadingText="正在加载更多...">
</ion-infinite-scroll-content>
</ion-infinite-scroll>
步骤3:在事件处理函数做数据的操作,最后要结束刷新动作

练习:创建一个page:demo06-lianxi (:-16:50)
步骤1:在demo06-lianxi.ts中准备一个空的数组
步骤2:在demo06-lianxi.html中指定
一个按钮(加载更多)
一个支持侧滑动列表项的列表(列表项隐藏 一个叫做删除的按钮,点击删除,将当前 的列表项从列表中移除掉)
步骤3:点击按钮(加载更多),向数组中插入20条随机的数据,最终显示在列表


3、card
卡片是为了更好的展示数据
<ion-card>
<ion-card-header></ion-card-header>
<ion-card-content></ion-card-content>
</ion-card>

4、grid
ionic中的grid是基于flexbox来封装而来的,
帮助实现自定义的布局

flexDirection 指定主轴
justifyContent 沿着主轴对齐
alignItems 沿着交叉轴对齐

基本用法:
<ion-grid>
<ion-row>
<ion-col></ion-col>
<ion-col></ion-col>
</ion-row>
<ion-row>
</ion-row>
</ion-grid>
基本配置:
①指定列宽: <ion-col col-*></ion-col>
②设置行所有的列纵向对齐的方式:
align-items-center/start/end
③设置某一列在行中的纵向对齐方式:
align-self-center/start/end
④横向对齐
justify-content-start/center/end
⑤偏移量
offset-*
⑥右推或左拉
push/pull-*

5、轮播图
ion-slides
autoplay自动播放的时间间隔
loop 轮询
pager 显示指示器
effect 动画效果
speed 动画的速度(持续的时间)
paginiationType 指示器的类型
direction 方向

<ion-slides autoplay=1000 loop=true
pager=true effect="cube" speed=3000
paginationType="fraction"
direction="vertical">
<ion-slide>
123
</ion-slide>
<ion-slide>
456
</ion-slide>
<ion-slide>
789
</ion-slide>
</ion-slides>

6、支持滚动的容器(ionScroll)
<ion-scroll scrollX="true" scrollY="true">
</ion-scroll>

注意事项:
①指定宽度或者高度
②scrollX/scrollY

7、常见的窗口的用法
7.1 loading
显示一个正在加载中的提示窗口

import {LoadingController} from 'ionic-angular'

constructor(private myLoadingCtrl:LoadingController){}

var myLoading = this.myLoadingCtrl.create({
content:'',
duration:,
spinner:'bubbles'
});

myLoading.present();
myLoading.dismiss();

7.2 actionSheet
显示一个由多个选项构成的从下往上弹出的窗口

import {ActionSheetController} from 'ionic-angular'

constructor(private myASCtrl:ActionSheetController){}

var myActionSheet = this.myASCtrl.create({
title:'',
buttons:[
{
text:'',
handler:()=>{},
role:'cancel/destructive'
}
]
});

myActionSheet.present()

7.3 alert
警告、确认、输入提示
import {AlertController} from 'ionic-angular'

constructor(private myAlertCtrl:AlertController){}

var myAlert = this.myAlertCtrl.create({
title:'',
message:'',
inputs:[
{placeholder:""}
],
buttons:[
{
text:'',
handler:(result)=>{
//result是输入框的数据 result[0]
}
}
]
});

myAlert.present()


7.4 toast
用在用户操作之后通过一个通知告诉用户操作的结果
import {ToastController} from 'ionic-angular'

constructor(private toastCtrl:ToastController){}

var myToast = this.toastCtrl.create({
message:'',
duration:,
position:'top/middle/bottom',
showCloseButton:true,
closeButtonText:''
})

myToast.present()

7.5 modal
自定义的模态窗口的实现

基本用法:
import {ModalController} from 'ionic-angular'

constructor(private modalCtrl:ModalController){}

var myModal = this.modalCtrl.create(//要显示的页面类)

myModal.present()

进阶知识:
如果关闭?
ViewController
import {ViewController} from 'ionic-angular'

constructor(private viewCtrl:ViewController){}

this.viewCtrl.dismiss()

参数的传递和接收?
①传递
this.viewCtrl.dismiss(123)
②接收
this.myModal.present()
this.myModal.onDidDismiss((result)=>{
//result就是模态窗在被关闭时所携带的参数
})


8、表单
ionic中的表单是通过ionList和ionItem来进行管理的

8.1 输入框
根据label展示方案的不同,共有五种移动端的写法
<ion-label></ion-label>
<ion-label fixed></ion-label>
<ion-label floating></ion-label>
<ion-label stacked></ion-label>
不写标签
8.2 复选框
<ion-checkbox></ion-checkbox>

8.3 单选框
<ion-list radio-group>
<ion-item>
<ion-radio></ion-radio>
</ion-item>
</ion-list>

8.4 滑动开关
<ion-toggle></ion-toggle>

8.5 滑动组件
<ion-range></ion-range>

8.6 下拉菜单
<ion-select>
<ion-option></ion-option>
</ion-select>

9、tabs
步骤1:引入tab被选中时 要加载的页面类
import {HomePage} from '***'
步骤2:将页面类保存在当前组件中
tabHome = HomePage;
步骤3:
<ion-tabs>
<ion-tab [root]="tabHome" tabIcon="" tabTitle=""></ion-tab>
<ion-tab></ion-tab>
<ion-tab></ion-tab>
</ion-tabs>

十二、Ionic中处理导航和传参(重点)
导航:
js:
步骤1:引入必要的类
import {NavController} from 'ionic-angular'
import {DestinationPage} from '..'
步骤2:实例化
constructor(private navCtrl:NavController){}
步骤3: 跳转
this.navCtrl.push(DestinationPage)

属性:
步骤1:引入
import {DestinationPage} from '..'
步骤2:保存
detail = DestinationPage
步骤3:调用
<any [navPush]="detail"></any>

传参:
①明确发送方和接收方
②发送
this.navCtrl.push(Demo16DetailPage,10)

[navPush]="detail" [navParams]="10"
③接收
import {NavParams} from 'ionic-angular'

constructor(private navParams:NavParams){}

this.navParams.data

十三、Ionic中page类的生命周期
ionViewCanEnter //守护当前pages是否可以进入
ionViewCanLeave//守护当前pages是否可以离开
ionViewDidLoad //加载一次
ionViewWillEnter //准备进入
ionViewWillLeave //准备离开
ionViewWillUnload//加载一次


this.navCtrl.pop()//怎么返回上一页
this.navCtrl.canGoBack() //返回值是true/false
//在某一个tab中,选中第0个tab
this.navCtrl.parent.select(0)

十四、Ionic的项目

(组件、基本语法、组件间通信、网络通讯、路由)

十五、React概述
React的应用广的领域中:
ReactJS
ReactNative
ReactVR
所有React中的技术都是基于五大核心概念的

slogan: learn once,write anywhere

1、what
React是facebook推出的,用来构建ui的js的库
2、why
①大量的DOM操作导致的浏览器性能瓶颈问题
VDOM (virtual DOM)
②代码增多,导致开发和维护越来越麻烦
单向数据流
3、优点
①采用声明式写法
②高效
虚拟DOM
③灵活
方便的搭配其它库来使用
④jsx
react支持jsx的语法,不是一种新的语言,是允许在js中直接写标签
⑤组件
组件是可被复用的视图
4、搭建环境
方式1:直接引入对应的js文件
方式2:基于cli
npx create-react-app my-app
cd my-app
npm start

十六、五大核心概念以及核心思想
补充:C:\Users\web\.vscode\extensions

1、核心思想:
组件的封装和复用

2、核心概念
2.1 jsx
两个基础语法:
①允许在js直接写标签(遇到<,就会用html解析)
②在标签通过{}做运算 (遇到{,就会用js来解析)

注意事项:
①要同时渲染多个,要放在同一个顶层标签中
②注释
{/* it is a comment*/}

2.2 组件
回顾:
Vue
Vue.component('demo01',{
components:{}
})
Angular
@Component({
selector:'demo01',
templateUrl:'',
styleUrls:[]
})
export class Demo01Component{}

React中组件类的创建和使用
2.1 创建
var Demo01 = React.createClass({
render(){
return 组件要渲染的模板
}
});
2.2 使用
<Demo01></Demo01>
2.3 注意事项
①组件类的命名要遵循全驼峰式的命名方式
②return后第一个标签不要换行
③不允许直接渲染多个
④每一个标签都要有自己的结束标记

复合组件:就是一个组件,只不过在此组件中调用了其它的组件

2.3 props(重点)
回顾:
Vue:
<son sonName='zhangsan'></son>
Vue.component('son',{
props:['sonName']
//this.sonName
})
Angular:
<son sonName='zhangsan'></son>
import {Input} from '@angular/core'
export class SonComponent{
//接收
@Input() sonName = "";
//this.sonName
}

React:
①props的基本用法(父--》子)
步骤1:通过自定义属性传值
<MyHeader myTitle='123'></MyHeader>
步骤2:通过props对象接收
在MyHeader组件内部接收:this.props.myTitle

②进阶知识1(this.props.children)
任何一个组件内部,都有一个props对象,该对象中对应的key和组件被调用时属性的名称是一一对应的;但是有一个是例外的
this.props.children (类型是不确定的,如果有一个子标签--》对象 多个-->数组,一个都没有--》undefined)

//this.props.children
//官方建议的遍历工具:
React.Children.map(this.props.children,(value,key)=>{
//value就是子标签
})
③进阶知识2 (子--》父)

步骤1:父组件定义一个有参数方法
login:function(uname){
//uname就是子组件传来的数据
}
步骤2:将方法通过自定义属性传递给子组件
<son func={this.login}></son>
步骤3:子组件可以调用父组件通过属性来传递的方法,同时将值通过参数传递给父组件
this.props.func('zhangsan')

问题:
在事件绑定事件处理函数,想自定义传参怎么解决??
<button onClick={this.handleClick}></button>


2.4 ref
帮助通过一个引用的名称,找到某一个组件的实例或者一个dom元素

步骤1:指定ref
<Son ref="mySon"></Son>
步骤2:通过ref指定的名称找到元素或者组件
this.refs.mySon

2.5 state
功能1:处理数据
初始化:
getInitialState:function(){
return {count:1}
}

this.state.count

this.setState({count:2})
this.setState({count:2},()=>{
//当本次状态写操作成功之后会执行的
})
功能2:绑定的效果(状态中的数据绑定到视图中)

练习:demo14_lianxi.html (:- 11:25)
步骤1:创建一个组件,SwitchComponent,该组件中渲染一个按钮就可以。
作为根组件来渲染
步骤2:按钮中的文本内容(默认显示关):开/关

注意事项:
React官方:
①顺序
建议将render方法放在组件的最后一个位置,最前边放的是生命周期的钩子函数或者react官方提供的其他方法(getInitialState),
中间应该放的是自定义的方法
②react编程时,方法主要分为两类,一类是自带的(getInitialState/render/componentDidMount/...),一类程序员自定义的


3、第一个Demo
知识点1: ReactDOM.render()
ReactDOM.render(A,B)
实例:
ReactDOM.render(
<h1>hello react</h1>,
document.getElementById('example')
)
知识点2:babel
babel是一个js的编译器compiler(可以将es6或者jsx转换为浏览器现在能够识别的语法)
<scrip type='text/babel'></script>
知识点3:jsx(浏览器默认是不识别的,需要babel转换)
jsx(javaScript xml)并不是一种的语言,只不过是允许在js中写标签


4、React中组件的生命周期
回顾:
Vue:
create/mount/update/destroy
Angular:
ngOnInit/ngOnChanges/ngOnDestroy
Ionic:
ionViewCanEnter
ionViewWill/DidEnter
ionViewWill/DidLeave
ionViewCanLeave
React:
三个阶段:mount/udpate/unMount

对应的钩子函数:
componentWill/DidMount:做初始化工作
componentWill/DidUpdate:根据数据的变化 做处理
componentWillReceiveProps:当属性传来的值 发生变化的时候会执行(允许修改状态的)

componentWillUnmount:做清理工作

注意事项:
①要想通过ref找一个元素,必须得等到componentDidMount或者之后的阶段才可以
②当状态或者属性传来的值发生变化的时候,才会执行和update相关的钩子函数
③不允许在componentWill/DidUpdate中去执行和状态写操作相关的操作,这会导致死循环(耗尽资源)
④不允许修改通过属性传来的值(只读)
//报错:this.props.** = **;


5、受控表单元素的处理(并不是所有的表单元素都得按照受控的方式来处理)
在reactjs进行编程,如果表单元素出现:value/checked/selected等相关属性;表单元素就不受我们控制;将这样的表单元素称之为受控的表单元素

解决方案1:
变成非受控的表单元素(value-->defaultValue)
解决方案2:
①初始化状态
getInitialState:function(){
return {addr:'bj'}
}
②将状态的值绑定value
<input value={this.state.addr}/>
③onChange指定的事件处理函数中 完成状态的写操作
handleChange(e){
this.setState({addr:e.target.value});
}
<input onChange={this.handleChange} value={this.state.addr}/>


6、进阶知识
ReactJs本身并没有提供任何的指令
①循环
{
this.state.list.map(()=>{
//在迭代函数中 返回要重复创建的元素
return <li></li>
})
}
②判断
方案1:当判断条件比较简单时,可以通过短路逻辑(逻辑与运算来实现)
{
expression && 渲染的内容
}
方案2:当判断条件比较复杂时,可以封装一个方法
showSth(){
//做运算,得到最终一个结果
if(真){
//返回条件为真时要显示的内容
}else
....
}

{this.showSth()}
③事件传参
Vue:
<button @click="handleClick(1)"></button>
Angular:
<button (click)="handleClick(1)"></button>
小程序:
<button data-uname="" bindTap= ></button>
React:
<button onClick={()=>this.handleClick(0)}>
删除
</button>


十七、RN(ReactNative)概述
React Native:
Build native mobile apps using JavaScript and React
(使用React中基本语法和js基本知识,来完成原生的移动端的应用程序的开发)

(竞品:flutter cordova weex reactNative)

如何来使用RN做原生开发?
通过react基本语法和js,调用RN所封装的各种组件 ,在运行时,就会被编译成当前平台下的原生的控件

搭建环境:
步骤1:准备模板项目
将rn.zip拷贝到C:\xampp\htdocs\framework\react;解压缩;进入到rn文件夹,将myapp.zip解压缩

vscode打开C:\xampp\htdocs\framework\react\rn\myapp

启动命令行终端: npm start
(可以在浏览器中输入http://localhost:8081来进行访问)

步骤2:准备模拟器
①启动
②安装apk文件
C:\xampp\htdocs\framework\react\rn\myapp\android\app\build\outputs\apk
③启动安装后得来的myapp
④正确的设置要连接的开发服务器的地址和端口
172.163.100.191:8081
摇一摇--》Dev Settings-->Debug Server Host & Port for device-->在输入框中输入地址和端口 保存
⑤摇一摇--》reload 重新载入


准备模板有很多方案:
npm install -g expo-cli
expo init AwesomeProject
cd AwesomeProject

开发技巧:
如何查看console所输出的日志信息:
摇一摇--》debug js remotely--》在浏览器中打开一个新的标签页,在终端中查看log日志信息

十八、RN中基础知识
1、自定义一个组件并调用
①创建
import React,{Component} from 'react'

export default class Demo01 extends Component{
render(){
return 渲染的内容
}
}
②调用
案例:在index.android.js所封装的myapp中调用自定义组件:
引入: import Demo01Component from './app/components/demo01_first'

调用:<Demo01Component></Demo01Component?

注意事项:
①不允许调用html标签
②使用一个组件 都要先去引入才能使用
③要注意类导出和引入的方式
建议:导出加上default

2、state
初始化
constructor(){
super();
this.state = {count:1,name:'lucy',age:20}
}
读写操作和ReactJS中是保持一致的.

3、StyleSheet
import {StyleSheet} from 'react-native'

//创建要复用的样式
var myStyles = StyleSheet.create({
myText:{
color:'red',
fontSize:30
},
myImage:{
width:100,
height:100
}
})

//调用封装好的样式
<Any style={myStyles.myText}></Any>

4、自定义布局(FlexBox)
http://weibo.com/1712131295/CoRnElNkZ?ref=collection&type=comment

flexDirection 主轴方向
justifyContent 沿着主轴的对齐
alignItems 沿着交叉轴的对齐

主轴:column

5、发送网络请求
fetch("")
.then((response)=>response.json())
.then((result)=>{
//result就是可以直接使用的数据
})

十九、RN中常见的内置组件

1、Text
渲染文本内容
import {Text} from 'react-native'
<Text>123</Text>
2、View
指定一个容器
import {View} from 'react-native'
<View>
//嵌套的组件
</View>
3、Button (onPress)
import {Button} from 'react-native'
<Button title='' onPress={}></Button>

注意事项:
事件处理函数 如果需要用到组件实例对象中的this或者其他,推荐定义成箭头函数的形式
handlePress=()=>{

}
4、Image
import {Image} from 'react-native'
//本地图片
<Image source={require('../imgs/3.jpg')}></Image>
//服务器端的图片
<Image source={{uri:""}} style={{width:100;height:100}}></Image>

注意事项:
①加载服务器端的图片必须设置宽 高
②加载本地资源图片时,不允许在require()方法中做任何的运算
5、FlatList
是RN中一个高性能的列表展示组件
import {FlatList} from 'react-native'

//有参数有返回值的
//info是一个对象:item/index
showItem(info){
return <Text></Text>
}

<FlatList data={} renderItem={this.showItem}>
</FlatList>

注意:
如何指定key提升性能?
6、TextInput(onChangeText)
定位:获取用户输入的信息
<TextInput
secureTextEntry={true}
placeholder=""
onChangeText={}
value=""
></TextInput>
7、Switch (onValueChange)
Switch默认就是一个受控的表单元素
处理方案:
①初始化状态
②将状态的值绑定到Switch的value
③onValueChange对应的事件处理函数中 完状态的写操作
8、TouchableOpacity
是一个容器,放在该容器中的组件,在按下时,是会有透明度渐变效果的

<TouchableOpacity onPress={}></TouchableOpacity>

9、综合练习:
使用RN实现ToDoBox
①搞定所有的组件的静态模板
②实现add (:- 10:30)
(点击ToDoInput的add时,将输入框的值传递给ToDoBox;在ToDoBox中接收到传来的输入框的值,保存在状态(状态的类型:数组),在成功保存之后,打印
④将数组通过自定义属性传递给ToDoList
⑤ToDoList接收到属性传来的数组,遍历,创建多个ToDoItem
(:- 11:35)
⑥ToDoList在调用ToDoItem,将显示的数据传递给ToDoItem
⑦完成:在ToDoItem中的删除按钮按下,将当前的下标传递给ToDoBox,ToDoBox接收到下标时,从数组中删除指定下标的元素
⑧点完添加按钮之后,清空输入框的内容
10、ScrollView
功能:实现一个支持滚动的容器
用法:
import {ScrollView} from 'react-native'
<ScrollView></ScrollView>

实现固定页脚的效果:
<View style={{flex:1}}>
<ScrollView></ScrollView>
<View>
<Button></Button>
</View>
</View>

11、列表的扩展功能
①加载更多
<FlatList onEndReached={}></FlatList>

②实现指定key来提升性能的效果
FlatList在渲染列表项时,如果给渲染的列表项绑定key属性是不会生效的

解决思路:将data所指定的数组类型 改为对象数组,每个对象都必须包含一个属性key(对应的值要保证唯一性)

data={[{key:0,**},{}]}
12、ActivityIndicator
功能:显示一个加载中的指示器
用法:
import {ActivityIndicator} from 'react-native'

<ActivityIndicator size="large/small" color="">
</ActivityIndicator>


二十、ReactNavigation
回顾:
Vue/Angular:
路由模块:建立组件和url之间的映射关系
①路由的基本用法
举例:Vue
步骤1:安装并调用vueRouter插件
步骤2:<router-view></router-view>
步骤3:创建app要用到的各个组件
步骤4:配置路由词典(一个由路由对象构成的数组)
list = [{path:'',component:**,children:**},{}]
步骤5:测试url和组件是否匹配

②导航
this.$router.push()

import {Router} from '@angular/core"
private myRouter:Router
this.myRouter.navigateByUrl()

③传参
发送方和接收方
配置接收方的路由地址、接收参数
Vue:this.$route.params
Angular:
import {ActivatedRoute} from '@angular/router'

发送

④嵌套
路由嵌套:在一个路由对象中嵌套了其它的路由对象
[
{
path:'mail',
component:MailComponent,
children:[
{path:'inbox',component:Inbox}
....
]
}
]

⑤守卫
Vue:
beforeEach
Angular
路由对象中调用路由守卫服务:
。。。


功能:
Routing And Navigation for ReactNative apps
提供的导航方案:
StackNavigator
TabNavigator
DrawerNavigator(https://reactnavigation.org/docs/en/drawer-based-navigation.html)

基本用法:
步骤1:安装包
yarn add react-navigation
# or with npm
# npm install --save react-navigation
步骤2:创建app要用到的各个组件
步骤3:配置路由
import {createStackNavigator} from 'react-navigation'
import Demo17Login from '***'


var MyNavigator = createStackNavigator({
'login':{
screen:Demo17Login
},
'setting':{
screen:***
}
})

AppRegistry.registerComponent(
'myapp',
()=>myNavigator
)

注意事项:出现在createStackNavigator方法中的配置对象的第一个keyValue是默认要显示的页面
步骤4:测试

跳转:
this.props.navigation.navigate("目的地的路由地址")

传参:
步骤1:明确发送方和接收方
步骤2:发送
this.props.navigation.navigate('目的地地址',{pid:10})
步骤3:接收参数
方案1:
this.props.navigation.state.params.pid
方案2:
this.props.navigation.getParam('pid')

二一、项目
优化建议:
将需要复用的数据或者方法,封装起来以方便复用
比如:app/utils/global.js 封装东西 其它组件引入调用即可
附加参考网址,有兴趣了解下
https://react.docschina.org/ react
https://developers.weixin.qq.com/miniprogram/dev/api/ 小程序API
https://segmentfault.com/ 思否
https://www.cnblogs.com/xiaohaifengke/p/7308943.html vue之better-scroll的封装,包含下拉刷新,上拉加载功能
https://blog.csdn.net/TWFKXP/article/details/80574987 BFC
https://mint-ui.github.io/#!/zh-cn mint-ui
http://jsonplaceholder.typicode.com/ json
https://blog.csdn.net/lijia_1983370657/article/details/80489979
http://element-cn.eleme.io/#/zh-CN
http://mockjs.com/
https://www.cnblogs.com/pssp/p/5216085.html
https://www.sass.hk/guide/
https://reactnavigation.org/
https://segmentfault.com/a/1190000013336235
https://juejin.im/post/5a954add6fb9a06348538c0d
http://weex.apache.org/cn/guide/index.html
https://reactnative.cn/
https://segmentfault.com/a/1190000011358507
https://segmentfault.com/a/1190000008879966
http://www.bejson.com/
https://www.jianshu.com/u/92ffdfb520e7
https://www.jianshu.com/p/f43fe49065a0

展开阅读全文
打赏
0
0 收藏
分享
加载中
更多评论
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部