前端学习总结
14_WEBAPP
day1
-
NativeApp、WebApp、HybridApp对比
-
1、WebApp
- 网页应用,比如说网页版qq、网页版微信 具备跨平台运行的优势,但是如果在手机访问 每次都需要输入网址,比较麻烦
-
2、NativeApp
- NativeApp又叫原生应用, 是借助SDK提供的原生组件和服务进行编程而生成的本地App。 比如说我们经常提到的Android开发、iOS开发
-
3、HybirdApp
- HybirdApp又叫混合编程, 是介于WebApp和NativeApp之间的app, 兼具NativeApp良好的用户交互体验的优势、WebApp跨平台开发的优势
-
4、对比
-
-
搭建Android的开发环境
-
1、配置JDK(java develop kit)
-
2、配置SDK(software develop kit)
- 下载并使用ADT (Android Developer Tools)
-
可以去www.androiddevtools.cn下载对应工具
-
-
如何新建一个Android工程
-
1、找到Eclipse
-
2、File->New->Android Application Project
-
3、填写工程信息
-*
-*
-
5、运行Android项目
- 找到项目,点击右键,runAs AndroidApplication
-
4、目录简介
- 子主题
-
5、使用注意事项
- ActivityManager: Warning: Activity not started, its current task has been brought to the front 原因是由于对工程没有做任何修改,就去重复编译运行
- 工程有×号 根据x号 找到是哪个目录下的具体的文件的问题,找到出错的那一行根据提示解决问题
- window->Reset Perspective(恢复默认视图)
-
day2
-
创建一个HybridApp并运行起来
-
1、在webStorm中编写web代码
-
2、将前端代码拷贝到项目的assets目录下边
-
3、编写少量的java代码
-
WebView组件: what? 是一个网络视图组件,加载对应的html when? onCreate方法 where? 混合开发 how? WebView wv = new WebView(getApplicationContext());
-
步骤
- //创建一个网络视图 WebView wv = new WebView(getApplicationContext()); //设置允许执行js操作 wv.getSettings().setJavaScriptEnabled(true); //载入本地的网页 wv.loadUrl("file:///android_asset/index.html"); //将网络视图作为App的视图 setContentView(wv);
-
允许网络通信: androidManefiest.xml文件,在标签页中找到permissions,点击add添加 INTERNET。
-
-
4、注意事项
-
日志输出
- //查看控制台的日志输出 wv.setWebChromeClient(new WebChromeClient(){
@Override @Deprecated public void onConsoleMessage(String message, int lineNumber, String sourceID) { // TODO Auto-generated method stub super.onConsoleMessage(message, lineNumber, sourceID);
Log.e("test", "内容为"+message+" 行号为"+lineNumber);}
});
-
允许执行js
- wv.getSettings().setJavaScriptEnabled(true);
-
-
-
Ionic概述
-
Ionic是一个针对移动端的 实现类似原生应用程序用户体验的框架
-
特点
- 1、Ionic是依赖于Angular和Cordova(是一个平台,提供了 js的接口,支持通过编写js来实现对于智能设备底层硬件的调用)
- 2、Ionic有着强大的命令行的支持
- 3、Ionic有着丰富的组件和图标, 可以让项目更美观、更符合移动端的显示效果
-
-
Ionic环境搭建
- 步骤1:通过npm安装ionic cordova
npm install -g ionic cordova - 步骤2:通过ionic去创建一个基于ionic的模板项目
ionic start myApp blank ionic start myApp tabs ionic start myApp sidemenu - 步骤3:启动开发服务器
cd myApp ionic serve -l - ionic中常见指令
-
-
page的创建和使用基本步骤
-
创建page
- 步骤1: ionic g page demo01-basic
- 步骤2: src/pages找到demo01-basic文件夹下 demo01-basic.ts 数据和方法的指定 demo01-basic.html 模板内容的指定
-
使用page
- 步骤1:声明组件 找到app目录下app.module.ts文件, 引入Demo01BasicPage,在declarations和 entryComponents声明
- 步骤2:在app目录app.component.ts
-
设置rootPage为Demo01BasicPage
-
AlertController
-
给用户显示alert/prompt/confirm窗口
-
具体使用步骤
- ①import {AlertController} from 'ionic-angular'
- ②实例化
-
constructor(public alertCtrl:AlertController){}
- ③创建窗口
- let myAlert = this.alertCtrl.create({
title:'', subtitle:'', message:'', buttons:[ {text:'btn1',handler:()=>{}} ], inputs:[ {type:'',placeholder:'',value:''} ]
})
- ④显示窗口
- myAlert.present();
day3
-
ionic内置的颜色
- danger 红色 primary 蓝色 secondary 绿色 light 浅灰色 dark 黑色
如果需要自定义常用颜色名字,找theme/variables.scss 找$colors进行定义
-
buttons
- <button ion-button color="danger" clear/outline/round/block></button
- <button ion-button icon-left/right/only> home
-
card
-
list
- 3种常见的列表
- iconList
- <ion-list>
hello world
- avatarList
- <ion-list>
hello world
- thumbnailList
- <ion-list>
hello world
- 支持左滑右滑的列表
- <ion-item-sliding>
test01
关注 删除-
actionSheet
-
自地向上 滑出的菜单
-
实现方式
- import {ActionSheetController} from 'ionic-angular'
- constructor(public asCtrl:ActionSheetController){}
- let myActionSheet = this.asCtrl.create({ title:'', buttons:[ { text:'cancel', handler:()=>{}, role:'cancel' },{ text:'删除', role:'destructive', handler:()=>{} },{ text:'分享到朋友圈', handler:()=>{} } ] })
- myActionSheet.present();
-
-
fab
-
floating action button
-
实现方式
-
-
loading
-
实现加载中的提示窗口
-
实现方式
- import {LoadingController} from 'ionic-angular'
- constructor(private loadCtrl:LoadingController){}
- let myLoad = this.loadCtrl.create({ content:'', duration:3000 })
- myLoad.present();
-
-
toast
-
toast是在无论是android还是iOS原生组件都是由支持的, 为了让ionic项目实现时 更接近与原生的app,ionic封装了实现通知的类:toast
-
实现方式
- import {ToastController} from 'ionic-angular'
- constructor(private toastCtrl:ToastController){}
- this.toastCtrl.create({ message:'', duration:1500, position:top/bottom/middle })
- myToast.present();
-
day4
-
grid
-
ionic的grid是基于flexBox
-
基本使用
-
- 进阶
- 指定列宽
- <ion-grid>
- 如果一行中的列 都没有指定列的宽度
默认情况:均等分
- 如果一行中的列 指定列的宽度,其余的没有指定列宽的 将均等分剩余的宽度
- 指定列与列之间的偏移量
- <ion-grid>
- 行中列的纵向对齐方式
- <ion-row align-items-start/center/end></ion-row>
- 指定某一列在当前行中的对齐方式
- <ion-col align-self-center/start/end></ion-col>
- 行中各列横向布局方式
- 默认情况,是从左向右
- <ion-row justify-content-start/center/end>
- 调整列距离最左边或者最右边的边界的距离
- //将当前列 设置 向右移动3/12
//将当前列 设置 向左移动3/12
-
刷新
-
refresher 下拉刷新
-
步骤1
- 在模板中指定内容: 在ion-content的第一个子元素的位置
-
-
- 步骤2
- 绑定事件处理函数
ionRefresh
- <ion-refresher (ionRefresh)="doRefresh($event)">
<ion-refresher-content pullingText="" refreshingText=""
- 步骤3
- 在ionRefresh的处理函数中操作数据
和结束刷新动作
- doRefresh(myRefresher){
//操作数据 //结束刷新动作 myRefresher.complete(); }
- infiniteScroll
上拉加载更多
- 步骤1
- 在模板中指定内容:
在ion-content的最后一个子元素的位置
- 步骤2
- 绑定事件处理函数
ionInfinite
- 在模板中指定内容:
在ion-content的最后一个子元素的位置
<ion-infinite-scroll (ionInfinite)="loadMore($event)"> <ion-infinite-scroll-content loadingText="正在加载数据" loadingSpinner="bubbles/circles/dots"
- 步骤3
- 在ionInfinite的处理函数中操作数据
和结束刷新动作
- loadMore(myInfinite){
//操作数据 //结束刷新动作 myInfinite.complete(); }
-
forms
-
在ionic中 实现表单是靠内部实现ionList进行管理的
-
具体组件用法
-
复选框
-
-
- 单选框
- <ion-list radio-group>
北京
上海
广州
- 滑动开关
- <ion-list>
蓝牙
- 下拉菜单
- <ion-list>
选择喜欢的颜色
red
green
- 滑动组件
- <ion-list>
是否同意
0
100
- 输入框
- fixed
- <ion-list>
用户名
- placeholder
- stacked
- <ion-list>
用户名
- floating
- <ion-list>
用户名
-
lifecycle
-
ionic中每一个页面 都有它自己的生命,会有从创建到消亡的过程
-
具体的生命周期处理函数
- ionViewDidLoad
- ionViewCanEnter
- ionViewWillEnter
- ionViewDidEnter
- ionViewCanLeave
- ionViewWillLeave
- ionViewDidLeave
- ionViewWillUnload
-
-
navigation
- ionic的page之间的跳转其实都是通过navController, 通过一套stack机制的入栈和出栈, 来实现前进和后退的
this.navCtrl.push(Demo02Page) this.navCtrl.pop(); - 跳转
- js
- 步骤1:
import {Demo02Page} from '...' - 步骤2: 跳转
- this.navCtrl.push(Dem02Page);
- 属性
- 步骤1:
import {Demo02Page} from '...' - 步骤2: 在当前的类中 定义一个变量保存Demo02Page
- destinationPage;
constructor(){ this.destinationPage = Demo02Page }
- 步骤3:属性绑定
- <button [navPush]="destinationPage"></button>
- 传参
- 传递参数
- js
- 步骤1:
import {Demo02Page} from '...' - 步骤2: 跳转
- this.navCtrl.push(Dem02Page,{id:10});
- 属性
- 步骤1:
import {Demo02Page} from '...' - 步骤2: 在当前的类中 定义一个变量保存Demo02Page
- destinationPage;
constructor(){ this.destinationPage = Demo02Page }
- 步骤3:属性绑定
- <button
[navParams]="{id:10}" [navPush]="destinationPage">
- 接收参数
- this.navParams.data.id
this.navParams.get('id')
-
modal
-
modalController可以帮助我们实现一些需要自定义的模态窗, 比如弹出的登录页、支付页面、菜单等
-
使用方式
- import {ModalController} from 'ionic-angular'
- constructor(private modalCtrl:ModalController){ }
- 创建模态窗中 要显示的组件或者页面 TestPage
- this.modalCtrl.create(TestPage).present();
-
-
slides
-
slides允许用户去滑动组件,从而来实现轮播图、新手教程等
-
基本用法
-
- 配置属性
- <ion-slides autoplay="1000" loop="true" effect="fade/slide/cube"
direction="vertical/horizontal" pager paginationType="bullets/fraction/progress" speed="1000"
-
tabs
-
tabs是用来在移动端的底部 充当导航条作用,可以点击不同的tab页面 切换到指定的不同的页面
-
实现方式
- 创建一个根页面 MyAppPage
- 创建需要显示的其它页面 ProductListPage CartListPage
- 在MyAppPage的页面类 中 引入 ProductListPage CartListPage, 定义类中的变量 productList,cartList, 进行赋值: this.productList = ProductListPage; this.cartList = CartListPage
-
在MyAppPage这个根页面中指定标签: <ion-tab tab-title="" tab-icon="" hideOnSubPages="true" [root]="productList"
<ion-tab tab-title="" tab-icon="" hideOnSubPages="true" [root]="cartList"
-
localStorage实现数组的读写
- 由于本地存储(localStorage/sessionStorage), 键值对是按照字符串进行存储的,如果说有需求:将数组存在 本地存储中, 要想实现该需求:json序列化和反序列化 ①数组中需要写入数据: 数组是可以存在对象中, 而对象是可以被序列化成一个json格式的字符串, 然后就可以本地存储的
②数组中需要读数据 从本地存储中 得到json格式的字符串, 反序列化得到对象,读取对象中属性就可以得到数组
15_REACT
day1
-
概述
-
介绍
- React(有时称为React.js 或ReactJS)是一个为数据提供渲染HTML视图的开源JavaScript库
-
历史
- React是由FaceBook的工程师Jordan Walke创建的,是受到php的HTML组件库XHP影响, React在11年时,刚开始是部署在FaceBook的newsfeed; 随后在12年时部署于Instagram,于13年5月在JSConf US宣布开源 14年成为facebook第一个在Github上达到1万star的旗舰开源项目, 15年3月在JSConf,FaceBook发布了React Native,可以使用React来构建nativeApp,并提出自己的理念“learn once,write anywhere”。 16年4月,发布V15正式版本,但是依然不够稳定,这毕竟是最新的技术
-
特点
- 声明式设计:采用声明范式,可以轻松描述应用 高效:通过对DOM的模拟,最大限度减少与DOM的交互 灵活:可以方便的搭配其它库来使用 JSX:是js语法的扩展 组件:构建组件,方便复用 单向相应的数据流
-
核心思想
- 封装组件
-
劣势
- 在你选择之前需要再考虑一下: ①一开始 React 会极大地减慢你的开发。理解props、state以及组件通信如何工作并不是很简单,并且文档信息错综复杂。理论上,这将会被克服,你的整个团队都上道之后,开发速度上就会有一个很大的提升。 ②React 不支持 IE8 以下的任何浏览器,以后也绝不会。 ③如果你的应用/站点不需要频繁的动态页面更新,你可能为了很小的功能而编写大量的代码。 ④你会改造很多轮子。React 很年轻,并且因为没有权威的方式来处理事件、组件通信,你必须从零开始创建大量的组件库。你的应用是否有下拉菜单,可调整大小的窗口,或者 lightbox?你同样必须从零开始写这些。
-
-
搭建React的开发环境
-
引入react.js react-dom.js browser.js 三个js文件
-
demo
-
-
JSX语法
-
基本语法
-
遇到HTML标签(以<开头), 如果首字母是小写的,就用HTML来解析, 如果首字母是大写的,交给React按照组件去解析 遇到代码块(以{开头)就用js来解析
-
demo
-
-
-
组件
-
创建和引用
-
创建
- React 允许将代码封装成组件(component),然后像插入普通 HTML 标签一样,在网页中插入这个组件。React.createClass 方法就用于生成一个组件类
-
-
var HelloMsg = React.createClass({ render:function(){ return
TEST
} }) - 引用
- <HelloMsg/>
- 注意事项
- ①组件的名字 首字母必须是大写的,
遵循全驼峰式的命名方式 - ②在render返回要渲染的元素的时候, 第一个html标签 不能直接换行 - ③如果要返回多个元素,要放在一个顶层标签中
- 基本用法demo
-
- 复合组件
-
复合组件:将其他的组件 整合在一起 创建的新组件 积木+积木--》乐高机器人 - demo
-
-
props
-
介绍
- 组件的用法与原生的 HTML 标签完全一致,可以任意加入属性,比如 ,就是 HelloMsg 组件加入一个 name 属性,值为 daxu。组件的属性可以在组件类的 this.props 对象上获取,比如 name 属性就可以通过 this.props.name 读取
-
demo
-
children
-
this.props 对象的属性与组件的属性一一对应,但是有一个例外,就是 this.props.children 属性。它表示组件的所有子节点
-
demo
-
-
-
组件间通信
-
父与子通信
-
父组件中,在调用子组件时, 可以通过属性传值;子组件通过 props对象去获取传递来的数据
- 步骤1:传值 var Parent = React.createClass({ render:function(){ return } })
- 步骤2:接收值
var Son = React.createClass({
render:function(){
return
{this.props.tips}
} })
-
-
子与父通信
- 步骤1:在父组件定义一个带有参数的方法 var Parent = React.createClass({ rcvMsg:function(arg){ console.log(arg); }, render:function(){ return } })
- 步骤2:将父组件中的方法 传递给子组件 var Parent = React.createClass({ rcvMsg:function(arg){ console.log(arg); }, render:function(){ return } })
- 通过props去读取父组件传来的方法, 调用并完成传值 var Son = React.createClass({ sonName:'zhangsan', handleClick:function(){ this.props.funcRcv(this.sonName); }, render:function(){ return clickMe } })
-
兄弟通信
- 兄弟组件 有一个共同的父组件; 兄弟组件间通信方式 是依赖于共同的父组件; 把需要共享的数据放在父组件
-
-
refs
-
介绍
- 组件并不是真实的 DOM 节点,而是存在于内存之中的一种数据结构,叫做虚拟 DOM (virtual DOM)。只有当它插入文档以后,才会变成真实的 DOM 。根据 React 的设计,所有的 DOM 变动,都先在虚拟 DOM 上发生,然后再将实际发生变动的部分,反映在真实 DOM上,这种算法叫做 DOM diff ,它可以极大提高网页的性能表现 但是,有时需要从组件获取真实 DOM 的节点,这时就要用到 ref 属性
-
demo
-
-
react编程风格推荐
-
推荐1
- 方法顺序遵循生命周期放在前面, render() 方法放在最后
-
推荐2
- 事件处理函数的命名 采用 "handle" + "EventName" 的方式来命名
-
推荐3
- 事件函数作为属性时的命名 为了跟 react 的事件命名保持一致: onClick, onDrag, onChange, 等等,采用如下格式:
-
- 推荐4
- 元素跟 return 放在同一行
为了节约空间,采用下面的写法:
return
day2
-
state
-
3个基本操作
-
初始化
- getInitialState:function(){ return {opacityValue:0} }
-
读写
- this.state.opacityValue
- this.setState({opacityValue:0.1},function(){ //状态设置成功之后的处理函数 })
-
-
作用
- 将状态中的数据 绑定 到视图
-
{this.state.btnState?'开':'关'}
-
lifecycle
-
组件的生命周期在React主要 分为3个阶段:mount/update/unmount
-
处理函数
- componentWillMount
- componentDidMount
- componentWillUpdate
- componentDidUpdate
- componentWillUnmount
-
注意事项
- 如果要想通过ref去定位元素进行操作, 那么必须等到componentDidMount
- componentWill/DidUpdate(props,state) props或者state有变化的时候,才会调用和更新相关 的处理函数
-
-
表单受控元素
-
input指定了value, select指定了selected checkbox指定了checked 是一个表单受控元素
-
解决方案
- ①初始化状态
- ②将状态中的值 绑定给表单元素
- ③在onChange中 修改状态中的值
-
day3
-
todobox
-
组件的创建和使用
-
父与子通信
- todobox 有一个状态myList,通过属性传递给了todolist ...
-
子与父通信
- todoinput和todoitem点击add、delete按钮时 要去操作todobox中状态对应的数组
-
状态state
-
getInitialState:function(){ return myList:[] }
-
add/delete
- this.setState({myList:[]})
-
-
-
三连棋
- 在React编码中,虽然支持在js中 直接去编写html标签,但是jsx的语法毕竟是一个需要转换为 浏览器能够识别的语法,html标签不能像之前一样随便写: style={{opacity:1}}
- 三个组件 Square/Board/Game
- Board组件中涉及到state的读、初始化、设置
- Square组件按钮单击时,要设置board组件中的状态(子与父通信)
- Square组件要想显示x或者o,将board组件中状态对应的数组 传递给Square(父与子通信)
-
ReactNative概述
- RN是一个实现nativeApp的框架, 采用是React的核心思想(一切都是组件) 和核心概念(jsx/state/props/refs/component), 开发理念:learn once,write anywhere
当前所学习的版本:0.49 - why
- 开源免费
- 开发成本低(学习成本、时间成本)
- 可以真正的实现nativeapp的开发(相比hybrid/webApp运行更流畅)
- how
- 方式1
- create-react-native
- 方式2(建议)
- react-native-cli
-
ReactNative基础使用
-
开发时工作原理
- react-native start
- 启动了一个模拟器,安装一个myapp的apk结尾的文件, 然后设置开发服务器的ip和端口号
-
RN中的组件的使用
-
注意事项: ①在写ReactNative组件时候,返回的必须是ReactNative封装好的组件, 不能是div/p/ul/table... ②StyleSheet 属性的设置 都支持通过style去指定,如果自己创建的样式类,属性名必须是驼峰式
-
View
- 指定一个容器
-
Text
- 指定一段文本内容
-
StyleSheet
-
指定样式
- import {StyleSheet} from 'react-native';
- const myStyle = StyleSheet.create({ myRed:{ color:'red', fontSize:20 } })
-
-
-
day4
-
View
- 指定一个容器
-
Text
- 指定一段文本内容
-
StyleSheet
-
指定样式
- import {StyleSheet} from 'react-native';
- const myStyle = StyleSheet.create({ myRed:{ color:'red', fontSize:20 } })
-
-
Button
-
State
-
3个基本操作
-
初始化
- constructor(){ super(); this.state = { count:0 }; }
-
读
- this.state.count
-
写
- this.setState({count:1})
-
-
-
TextInput
- <TextInput placeholder="plz input sth" onChangeText={(data)=>{}}/>
-
Image
-
本地资源文件
- <Image source={require('./img/1.jpg')}/>
-
网络资源文件
- <Image source={{uri:'*****'}}/>
-
-
TouchabelOpacity
- 给任何一个元素 添加 点按时透明度变化的效果
hello world
-
fetch
-
fetch是由ReactNative所封装的一个处理与远程服务器端通信 的方法
-
使用方式
- fetch(url,{method:'get/post'}) .then((response)=>response.json()) .then((response)=>{ //response就是服务器端返回的结果 })
-
-
FlatList
-
是由RN所封装一个高性能的列表
-
使用方式
- <FlatList renderItem={(info)=>{ return {info.index} }} data={this.list}/>
-
-
keyboardAvoidingView
-
避免在进行表单操作时候,表单元素被弹出的键盘遮住的问题
-
如何使用?
- 在表单元素上层套一个容器keyboardAvoidingView
-
-
switch
- 滑动开关
-
ActivityIndicator
- loading 加载中的效果
-
导航
-
借助于ReactNavigation开源项目, 内部又细分为3个导航模式, 比如stackNavigator/tabNavigator/drawerNavigator
-
stackNavigator
- ①安装reactNavigation
-
npm install react-navigation - ②创建页面需要用到的各个组件,比如 ListComponent DetailComponent - ③配置路由词典 import {StackNavigator} from 'react-navigation'
const myRouter = StackNavigator({ myList:{ screen:ListComponent }, myDetail:{ screen:DetailComponent } })
AppRegistery.register( ()=>myRouter)
All_Frameworks(阶段框架总结)
Vue
-
day1
-
框架概述 framework
-
什么是框架
- 框架指的是一套非常优秀可被反复使用的代码, 帮助开发者解决一些复杂的问题。 比如jQuery帮助搞定简化DOM操作、老版本浏览器兼容问题
-
框架有啥好处
- 提高了代码的复用率 降低模块之间的耦合度 提高开发速度 提高代码质量
-
-
VueJS概述
-
what
- Vue.js(读音 /vjuː/,类似于 view) 是一套构建用户界面的渐进式框架。与其他重量级框架不同的是,Vue 采用自底向上增量开发的设计。Vue 的核心库只关注视图层,它不仅易于上手,还便于与第三方库或既有项目整合。 另一方面,当与单文件组件和Vue生态系统支持的库结合使用时,Vue也完全能够为复杂的单页应用程序提供驱动
-
-
Vue的开发模式 和 之前接触的jQuery、原生JSDOM操作是不同的, 之前要想修改视图,首先找元素; 在使用Vue时,专心把精力放在修改数据。 DOM驱动 ---》 数据驱动。
- where
- 饿了么 滴滴 阿里巴巴
gitlab。。。
实现UI层的渐进式的框架 VueJS可以用在很多地方,从简单的表单验证,到复杂的大型企业应用程序,Vue都可以胜任;核心库是实现UI层的。
- why
-
①非常好的中文文档 ②学习曲线比较缓和(容易上手) ③速度快 ④体积小 ⑤基于组件化(webcomponent)的开发方式 ⑥代码的可读性、可维护性比较好
- how
- cli
- #安装nodejs
nodejs.org/en/ #全局安装 vue-cli npm install --global vue-cli #创建一个基于 webpack 模板的新项目 vue init webpack my-project #安装依赖,走你 cd my-project npm install npm run dev
- js
- 直接下载,引入js文件即可
- 第一个例子
- <!DOCTYPE html>
- 双花括号
- 语法
- <any>{{表达式}}</any>
- 作用
- 执行表达式,将表达式的结果 输出到当前调用元素的innerHTML中
- demo
- <!DOCTYPE html>
{{car.brand}}
{{3+5}}
- Vue指令
- 循环指令
- 语法
- 语法1:
根据in关键词后的集合,去循环创建多个标签, 举例: myList:[100,200,300] {{tmp}}
语法2:
- demo
- <!DOCTYPE html>
<!-- Vue提供了一个循环的指令: v-for -->
<ul>
<li v-for="tmp in myList">
{{tmp}}
</li>
</ul>
<!-- v-for第二种语法:可以取到临时变量对应的index-->
<p v-for="(value,key) in car">
{{"key is "+key+" value is "+value}}
</p>
<p v-for="(value,key) in myList">
{{"key is "+key+" value is "+value}}
</p>
- 选择指令
- 语法
- <any v-if="表达式"></any>
v-if v-else-if v-else 根据表达式执行的结果的真假 来选择是否要挂载到DOM
- demo
- <!DOCTYPE html>
{{msg}}
仅会员可见
<p v-if="answer=='a'">A</p>
<p v-else-if="answer == 'b'">B</p>
<p v-else-if="answer == 'c'">C</p>
<p v-else>D</p>
- 事件指令
- 语法
- <any v-on:eventName="处理函数名字"></any>
通过v-on去给指定的事件绑定一个处理函数
- <button v-on:click="handleClick">clickme</button>
//通过@后边跟上事件的名字,和v-on:是一样的效果 <button @click="handleClick">clickme
- 注意事项
- 方法在定义时,要放在Vue实例的methods属性
new Vue({ methods:{ handleClick:function(){ //做一些操作 } } })
- demo
- <!DOCTYPE html>
{{msg}}
clickMe clickMe<select v-on:change="handleChange">
<option value="red">红色</option>
<option value="green">绿色</option>
<option value="blue">蓝色</option>
</select>
<form v-on:submit.prevent="handleSubmit">
<input type="checkbox"/>是否同意本站协议
<br/>
<button>登录</button>
</form>
- 其他常用指令
- v-bind
- 将变量中的值 通过 v-bind 绑定到元素指定的属性
img v-bind:src="myImage" a v-bind:href="myLink" v-bind:style='{backgroundColor:myBGColor}' v-bind:class='{myRed:isRed}' v-bind:disabled="!isValid"
v-bind也支持简写 a v-bind:href="myLink" ===》 a :href="myLink"
- v-show
- v-show="表达式" 根据表达式执行的结果的真假 来切换display显示还是隐藏
- <button v-show="hasMore">加载更多</button>
<p v-show="!hasMore">没有跟多数据可以加载了</p>
- v-html
- v-html="变量" 根据变量更新对应的innerHTML
- 双向数据绑定指令
- 双向数据绑定:
方向1:data --> view 之前所接触的循环、判断、显示隐藏等指令,主要的功能是将数据 绑定到视图; 方式:①双花括号 ②常见的指令
方向2:view --》 data 将表单控件中 用户操作的 结果 绑定到 数据 方式:v-model - demo
- 基础
- <input type='text' v-model=''kw"/>
{{kw}}
- 高级
- <input type="text" v-model.lazy="userAddress"/>
<p>{{"用户输入的结果为"+userAddress}}</p>
<!-- 有两个输入框,一个按钮,
点击按钮时将输入框输入的数据进行求和,将结果输出在控制台-->
<input type="number" v-model.number="num1"/>
<br/>
<input type="number" v-model.number="num2"/>
<br/>
<button @click="addSum">add</button>
<br/>
<!-- trim去掉收尾的空白字符-->
<input type="text" v-model.trim="myNotes"/>
<p>{{myNotes.length}}</p>
-
day2
-
自定义指令
-
步骤
-
创建
- new Vue({ directives:{ change:{ bind:function(){}, update:function(){}, unbind:function(){} } }, data:{ count:10 } })
-
-
-
bind方法以及update方法 都是有参数的, 一个是el,对应的是调用指令的元素 一个bindings,是一个对象:name/rawName/value/oldValue...
- 使用
- <div v-change='count'></div>
- demo
- new Vue({
directives:{ changeBackgroundColor:{ bind:function(el,bindings){ el.style.backgroundColor = bindings.value } } } })
- 自定义过滤器
- 过滤器:实现数据的筛选、过滤和格式化
就是把数据变的复合页面显示的要求 - 语法
- <any>{{表达式 | myFilter(arg1,arg2)}}</any>
- 创建过滤器
- new Vue({
filters:{ myFilter:function(myInput,arg1,arg2){ return 处理后的结果 } } })
- 组件的创建和使用
- 组件是一个可以被反复使用的 带有特定功能的 视图
- 组件化的好处
- ①提高开发速度
- ②提高代码的复用率
- ③降低耦合度
- ④提高代码的质量
- ⑤降低测试难度
- 组件的创建
- Vue.component(
'my-component',{ template:'渲染的元素' } ) - 注意事项:
- 当我们在组件中需要渲染多个元素的时候,
应该将多个元素放在一个容器,否则是有问题的
- 使用组件
- 像使用普通的html标签去使用
- 复合组件
- 组件树
- 复合组件并不是一个新的概念,就是一个普通的组件
只不过是由其他的组件构成的。
- 组件的生命周期
- 四个阶段
- create
- beforeCreate
- created
- mount
- beforeMount
- mounted
- update
- beforeUpdate
- updated
- destroy
- beforeDestroy
- destroyed
- demo
- 在组件挂载完毕之后,
启动定时器,来修改组件中元素的透明度
- mounted:function(){
setInterval(function(){ this.opacityValue+=0.1; if(this.opacityValue > 1){ this.opacityValue = 0; } }.bind(this),100) } -
hello
- watch
- 监听数据的变化
- ① 在data中 定义kw
- ②在组件中
- ③使用watch
- Vue.component(
'my-component', { watch:{ kw:function(){ //根据数据的变化做处理 } } } )
-
day3
-
组件间通信
-
props down (父组件 将数据 传递给子组件)
-
步骤1
-
步骤2
- 在子组件接收数据:
Vue.component('son',{
props:['myName','myAge'],
template:
<h1>{{myName}}</h1>})
- 在子组件接收数据:
Vue.component('son',{
props:['myName','myAge'],
template:
-
-
events up (子组件 将数据 传递给父组件)
-
步骤1
- 在父组件 调用 子组件时 通过v-on或者@绑定一个自定义事件 以及 对应的处理函数
- Vue.component('parent',{ methods:{ rcvMsg:function(msg){ //msg就是通过事件传递的数据 } },
-
-
-
template:'<son @customEvent="rcvMsg">' })
- 步骤2
- Vue.component('son',{
mounted:function(){ //在业务需要的时候 通过emit('customEvent',123) } })
- 父子组件通信
parent
- $refs
- 使用场景:父组件如果要想获取子组件中数据或者方法
- 步骤
- 1、给子组件要指定一个属性
- 2、通过引用名字mySon怎么得到子组件的实例? this.$refs.mySon
- $parent
- 在子组件中 获取 父组件的实例中数据或者方法
- 步骤
- this.$parent
- 兄弟组件通信
- 兄弟组件通信,可以借助于①一个空的 vue实例 ②event
- 步骤
- var bus = new Vue()
- 熊大 把 数据 发给 熊二
- 熊二
- bus.$on('msgToXiongEr',function(msg){})
- 熊大
- bus.$emit('msgToXiongEr',20);
-
day4
-
SPA
-
基本概念
- SPA(single page application),单一页面应用程序, 在一个完整的应用当中,只有一个完整的页面, 其它的都是些代码片段(模板)
-
工作原理
-
-
①解析url,得到完整页面的地址:index.html 加载过来 ②解析url,得到路由地址:/start ③根据该路由地址 去到路由词典中 查找对应的配置:component/children ④加载对应的页面,显示在一个容器当中
- 通过Vue官方提供的插件
vueRouter来实现SPA
- 1、实现SPA的基本步骤
- 1、引入vue-router.js
- 2、指定一个盛放代码片段的容器
- 3、创建业务所需的各个组件 - 4、配置路由词典
- 方式1
- const myRoutes = [
{path:'/myLogin',component:Login}, {path:'/myRegister,component:Register}, ]
const myRouter = new VueRouter({ routes:myRoutes })
new Vue({ router:myRouter })
- 方式2
- new Vue(){
router:new VueRouter({ routes:[ {path:'/login',component:Login} ] }) }
- 5、测试
在浏览器,修改路由地址,确认能够按照 我们的配置 去加载指定的组件
- 2、实现跳转的3种方式
- ①直接修改地址栏
中的路由地址 - ② js this.$router.push('/myLogin') - ③ router-link
jump
- 3、跳转如何来进行参数的传递
- 1、明确 发送方 接收方
- 2、配置接收方的路由地址
- {path:'/detail',component:MyDetail}
--> {path:'/detail/:id',component:MyDetail}
- 3、在接收方 接收数据
this.$route.params - 4、发送参数
- ①直接修改地址栏
中的路由地址
/detail/10
- ② js
index=20; this.router.push('/myDetail/'+this.index) - ③ router-link index=20; jump jump
- 4、路由的嵌套
- 现在有一个login(路由地址/login)、mail
(路由地址/mail),希望在mail的页面能够通过一些方式 来将收件箱或者发件箱的内容加载到mail页面中 - 步骤1:
- 需要在mail中的template中
指定一个盛放组件的容器
Vue.component('mail',{ template:`
- 步骤2
- 给收件箱和发件箱指定
对应的路由地址
- new Vue({
router:new VueRouter({ routes:[ {path:'/login',component:login}, {path:'/mail',component:mail, children:[ {path:'/inbox',component:Inbox} , {path:'/outbox',component:Outbox} ] } ] })
})
- 5、知识点的扩展
- 返回
this.$router.go(-1) - 异常处理 {path:'*',component:NotFound} - 别名 {path:'/list',component:MYLIST,alias:'/lists'} - 重定向 {path:'/userList',redirect:'/list'}
- vueResource
- this.$http.get/post
- demo
- this.$http
.get('data/test.json')
.then(function (response) {
console.log(response);
this.myList = response.data;
})
Angular
-
day1
-
Angular的概述
-
what
- 是Google在09年就推出的js的框架,适用在PC和Mobile
-
when
- 实现SPA,用在数据操作比较频繁的场景
-
why
- ①采用了组件化的开发方式 (提高了代码的复用率 降低了测试难度 提高了开发速度)
- ②增强了代码的可读性和可维护性
- ③angular相比之前的老版本引入了很多新的特性, 比如支持 typeScript,是一种强类型检查机制语言,对于面向对象开发 有更好的支持
-
how
-
方式1
- 采用官方提供的angular-cli工具, 进行基于angular项目的创建、开发、打包、部署。。。
-
方式2
- 从google所推出的基于angular的quickstart项目开始着手
-
-
-
组件的创建和使用
-
创建
-
①在src目录app目录,创建一个文件夹
-
②在该文件夹中 创建一个组件(都是**.component.ts)
-
③指定组件内容
- import {Component} from '@angular/core'
-
-
-
@Component({ selector:'demo01', template:'
Hello Component
' })export class Demo01Component{ }
- 使用
- 步骤1:到模块中声明
- ①在src目录的app目录 找app.module.ts
- ②引入对应的组件类
import Demo01Component from './demo01/demo01.component' - ③声明 @NgModule({ declarations:[AppComponent,Demo01Component] })
- 步骤2:<demo01></demo01>
- 补充
- import和export
是es6非常重要的概念, 是实现模块化的必不可少的两个关键词 export 是将当前的文件(类、方法、变量等)导出 (暴露自己的借口) import是将需要用到的模块 引入到当前的模块中 去使用 - es6的新特性,参考阮一峰 es6.ruanyifeng.com/#README - angular是以模块为基本单位,模块是 由各种各样的组件构成的
在使用angular进行开发时,创建的每一个组件 都得在对应的模块中去声明,才可以在该模块中 任何一个组件中去调用
-
day2
-
设计原则
-
YAGNI
- 不要写 不需要的代码
-
KISS
- 代码越简单越好
- 合理的注释 给变量和方法 命名遵循命名规则 让每一行代码 实现一个单一的功能
-
DRY
- Don't repeat youself
- 要善于进行代码的封装和重用
-
高内聚 低耦合
- 耦合:不同的组件或者不同的模块之间的关系 解耦:降低耦合的过程
-
ocp
-
open closed principle
-
开闭原则
- 开放:扩展 关闭:修改
-
-
最少知识法则
- 封装的功能单位要尽可能的小,只与自己相关
-
SRP
-
single responsibility principle
-
单一责任原则
- 每一个文件或者每一个方法, 就实现一个功能
-
-
-
angular常见的指令
-
循环
- *ngFor
- <any *ngFor="let tmp of list">
-
-
<any *ngFor="let tmp of list;let myIndex=index">
- 判断
- *ngIf
- <any *ngIf="expression"></any>
- 多重判断
- *ngSwitchCase
- *ngSwitchDefault
- demo
-
- hello lucy
- hello michael
- Hello
- 事件绑定
- 通过圆括号,在圆括号中指定的是触发的事件名字
- <button (click)="">clickMe</button>
- 属性绑定
- 调用某些元素时,在指定属性时,如果该值是一个变量,怎么办?
- <any [attribute]=“变量”></any>
<a [href]="myUrl"> - ngClass
- 动态样式类的绑定
- .myBlue{
color:blue }
- @Component({ selector:'demo03', template:'', styleUrls:['./test.css'] }) - ngStyle
- 完成动态样式的设置
- <p [ngStyle]="{color:myColor}"></p>
- 双向数据绑定
- ngModel
- 前提
- ngModel指令是由表单模块所提供的,
在给大家的模板项目的app.module.ts所创建的模块 默认是没有依赖表单模块的
如果要使用ngModel指令,首先需要当前模块,依赖于表单模块
①找到app.module.ts文件 ②引入表单模块 import {FormsModule } from '@angular/forms' ③指定依赖于表单模块 @NgModule({ imports:[FormsModule] })
- 使用ngModel
- 实现了将数据 绑定到了 视图
- <input type='text' [ngModel]="myAddr"/>
{{myAddr}}
- 双向数据绑定
- <input type='text' [(ngModel)]="myMsg"/>
{{myMsg}}
- 在进行双向数据绑定时,如何来监听数据的变化?
- <input type='text' [(ngModel)]="myMsg"
(ngModelChange)="getMsg($event)" />
getMsg(data){ //data就是用户所输入的数据,前提在绑定事件 时,必须指定参数为$event }
- 注意事项
- *ngFor和*ngIf等结构型指令 是不能直接放在一起用
通过ng-container来指定,避免出现不必要的html层级 不会影响html结构
-
day3
-
路由模块
-
1、路由模块的功能
- 路由模块是用来建立起SPA中 url和组件之间的映射关系, 同时支持参数传递、路由嵌套、路由守卫等功能
-
2、angular路由模块基本用法
-
①让appModule支持RouterModule
-
在app目录下,创建一个app.router.ts a-module-routing 创建一个自定义的模块, 是用来实现路由定义和配置的模块
-
到app.module.ts,指定依赖于自定义路由模块
- ①找到app.module.ts
- ②import {AppRoutingModule} from './app.router'
- ③在一个模块中如何指定依赖另一个模块呢? @NgModule({ imports:[AppRoutingModule] })
-
-
②指定一个盛放组件的容器
-
③创建需要用到的组件
-
④配置路由词典
- 在第一步创建的自定义模块中,有一个对象数组, const routes:Routes = [ //指定了路由地址为空时,要加载的组件 {path:'',component:TestComponent}, {path:'/test',component:TestComponent}, //指定了异常的处理 {path:'**',component:NotFoundComponent}, ]
-
⑤测试
- 保证设置的路由词典已经生效
-
-
3、angular组件跳转的方式
-
①直接修改地址栏
-
②通过js
-
①import {Router} from '@angular/router'
-
②实例化 在构造函数中实例化
- constructor(private myRouter:Router){ }
-
③调用方法实现跳转
- this.myRouter.navigateByUrl('/test')
- this.myRouter.navigate(['/test']);
-
-
③通过属性 routerLink routerLink经常用在a、button上面 来实现基本的导航功能
-
④返回上一页
-
①import {Location} from '@angular/common'
-
②在构造函数中实例化该类
- constructor(private myLocation:Location){ }
-
③ 调用方法
- this.location.back()
-
-
-
4、angular组件参数传递方式
-
方式1 (需要配置接收方路由)
-
①明确发送方 和 接收方
-
②配置接收方的路由地址 {path:'/detail',component:DetailComponent} --> {path:'/detail/:id',component:DetailComponent}
-
③如何接收参数
- import {ActivatedRoute} from '@angular/router'
- constructor(private aRouter:ActivatedRoute){ }
- this.aRouter.params.subscribe(function(data){ console.log(data.id); })
-
④发送参数
- this.myRouter.navigateByUrl('/detail/10')
- <a [routerLink]="'/detail/'+myId">jump
-
-
方式2 (不需要配置接收方路由)
-
①明确发送方 和 接收方
-
②如何接收参数
- import {ActivatedRoute} from '@angular/router'
- constructor(private aRouter:ActivatedRoute){ }
- this.aRouter.params.subscribe(function(data){ console.log(data.id); })
-
③发送参数
- this.myRouter.navigate(['/detail',{id:10}])
- jump
-
-
-
5、angular路由嵌套
-
-
angular整体架构
-
-
day4
-
组件间通信
-
props down
-
在父组件中,调用子组件时,是可以通过属性去传值
-
实现的细节
-
①传值
- @Component({
selector:'parent',
template:
<son age="20"></son>})
- @Component({
selector:'parent',
template:
-
②接收值 (在son这个子组件)
-
步骤1
- import {Input} from '@angular/core'
-
步骤2
- @Input() age="";
-
步骤3
-
调用数据
- this.age
-
-
-
-
-
events up
-
实现子组件 和父组件的通信
-
实现的步骤
-
绑定
-
在父组件中定义接收参数的方法
- rcvMsg(data){ //data就是通过事件传递来的数据 }
-
<son (customEvent)="rcvMsg($event)">
-
-
触发
-
步骤1
- import {Output,EventEmitter} from '@angular/core'
-
步骤2
- @Output() customEvent = new EventEmitter()
-
步骤3
- 在需要触发事件的时候,指定:
-
-
-
-
-
this.customEvent.emit('要发送的数据')
- 本地变量
<son #mySon>
- 类似于Vue中ref
- 实现细节
- 如果子组件有一个num=10
<son #mySon>,
在父组件的模板中,可以直接通过 mySon得到son组件的实例对象
{{"子组件的数据是"+mySon.num}}
在父组件的组件类中的方法中去调用怎么办? 可以通过方法传值
{{"子组件的数据是"+mySon.num}}
得到子组件实例- 管道
- 管道就是vue中提到的过滤器,
管道其实是一个方法,有参数有返回值的方法,主要是 用来在模板中 对于表达式执行的结果中数据进行筛选、过滤、格式化等处理, 要更符合数据的规范 - 内置管道
- date/json/uppercase/lowercase/number/currency/percent/slice
- date实现日期的格式化
- {{myDate | date:'MM-dd'}}
- json
- {{stu | json}}
- uppercase/lowercase
- {{stuName | uppercase}}
- number
- price=3.156
- 准备过滤成03.16
{{price | number:'2.2'}}
- currency
- price = 1024;
- {{price | currency:'USD':true:'3.2'}}
- percent
- slice
- tips = "hello world"
- {{tips|slice:2 }}
- 自定义管道类
- 实现细节
- 1、创建一个类
//a-pipe
- import {Pipe,PipeTransform} from '@angular/core'
- @Pipe({
name:'myCurrency' }) - export class CurrencyPipe implements PipeTransform{ transform(value: any, ...args: any[]): any { //必须有返回值 //value管道操作符前面传来的数据
} }
- 2、在模块中声明该组件类
- import {Demo18Pipe} from '...'
@NgModel({ delcarations : [Demo18Pipe] })
- 3、调用自定义管道
- {{price | myCurrecny}}
- 服务
- 只要是对应应用中逻辑的封装
- 实现的细节
- 创建一个服务类
- //a-service
- import { Injectable } from '@angular/core';
- @Injectable()
export class MyService{ func1(){
} }
- 使用服务
- import {MyService} from './my.service.ts'
- 在组件的元数据指定providers
- @Component({
providers:[MyService] })
- 实例化
- constructor(private myService:MyService){}
- 调用
- this.myService.func1();
webApp
-
day1
-
NativeApp、WebApp、HybridApp对比
-
1、WebApp
- 网页应用,比如说网页版qq、网页版微信 具备跨平台运行的优势,但是如果在手机访问 每次都需要输入网址,比较麻烦
-
2、NativeApp
- NativeApp又叫原生应用, 是借助SDK提供的原生组件和服务进行编程而生成的本地App。 比如说我们经常提到的Android开发、iOS开发
-
3、HybirdApp
- HybirdApp又叫混合编程, 是介于WebApp和NativeApp之间的app, 兼具NativeApp良好的用户交互体验的优势、WebApp跨平台开发的优势
-
4、对比
-
-
搭建Android的开发环境
-
1、配置JDK(java develop kit)
-
2、配置SDK(software develop kit)
- 下载并使用ADT (Android Developer Tools)
-
可以去www.androiddevtools.cn下载对应工具
-
-
如何新建一个Android工程
-
1、找到Eclipse
-
2、File->New->Android Application Project
-
3、填写工程信息
-*
-*
-
5、运行Android项目
- 找到项目,点击右键,runAs AndroidApplication
-
4、目录简介
- 子主题
-
5、使用注意事项
- ActivityManager: Warning: Activity not started, its current task has been brought to the front 原因是由于对工程没有做任何修改,就去重复编译运行
- 工程有×号 根据x号 找到是哪个目录下的具体的文件的问题,找到出错的那一行根据提示解决问题
- window->Reset Perspective(恢复默认视图)
-
-
-
day2
-
创建一个HybridApp并运行起来
-
1、在webStorm中编写web代码
-
2、将前端代码拷贝到项目的assets目录下边
-
3、编写少量的java代码
-
WebView组件: what? 是一个网络视图组件,加载对应的html when? onCreate方法 where? 混合开发 how? WebView wv = new WebView(getApplicationContext());
-
步骤
- //创建一个网络视图 WebView wv = new WebView(getApplicationContext()); //设置允许执行js操作 wv.getSettings().setJavaScriptEnabled(true); //载入本地的网页 wv.loadUrl("file:///android_asset/index.html"); //将网络视图作为App的视图 setContentView(wv);
-
允许网络通信: androidManefiest.xml文件,在标签页中找到permissions,点击add添加 INTERNET。
-
-
4、注意事项
-
日志输出
- //查看控制台的日志输出 wv.setWebChromeClient(new WebChromeClient(){
-
@Override @Deprecated public void onConsoleMessage(String message, int lineNumber, String sourceID) { // TODO Auto-generated method stub super.onConsoleMessage(message, lineNumber, sourceID);
Log.e("test", "内容为"+message+" 行号为"+lineNumber);}
});
- 允许执行js - wv.getSettings().setJavaScriptEnabled(true); -
-
Ionic概述
-
Ionic是一个针对移动端的 实现类似原生应用程序用户体验的框架
-
特点
- 1、Ionic是依赖于Angular和Cordova(是一个平台,提供了 js的接口,支持通过编写js来实现对于智能设备底层硬件的调用)
- 2、Ionic有着强大的命令行的支持
- 3、Ionic有着丰富的组件和图标, 可以让项目更美观、更符合移动端的显示效果
-
-
Ionic环境搭建
- 步骤1:通过npm安装ionic cordova
-
npm install -g ionic cordova - 步骤2:通过ionic去创建一个基于ionic的模板项目
ionic start myApp blank ionic start myApp tabs ionic start myApp sidemenu - 步骤3:启动开发服务器
cd myApp ionic serve -l - ionic中常见指令
-
- page的创建和使用基本步骤
- 创建page
- 步骤1:
ionic g page demo01-basic - 步骤2: src/pages找到demo01-basic文件夹下 demo01-basic.ts 数据和方法的指定 demo01-basic.html 模板内容的指定
- 使用page
- 步骤1:声明组件
找到app目录下app.module.ts文件, 引入Demo01BasicPage,在declarations和 entryComponents声明 - 步骤2:在app目录app.component.ts
设置rootPage为Demo01BasicPage
- AlertController
- 给用户显示alert/prompt/confirm窗口
- 具体使用步骤
- ①import {AlertController} from 'ionic-angular'
- ②实例化
constructor(public alertCtrl:AlertController){}
- ③创建窗口
- let myAlert = this.alertCtrl.create({
title:'', subtitle:'', message:'', buttons:[ {text:'btn1',handler:()=>{}} ], inputs:[ {type:'',placeholder:'',value:''} ]
})
- ④显示窗口
- myAlert.present();
-
day3
-
ionic内置的颜色
- danger 红色 primary 蓝色 secondary 绿色 light 浅灰色 dark 黑色
-
如果需要自定义常用颜色名字,找theme/variables.scss 找$colors进行定义
- buttons
- <button ion-button color="danger" clear/outline/round/block></button
- <button ion-button icon-left/right/only>
home
- card
- <ion-card>
- list
- <ion-list no-lines>
- 3种常见的列表
- iconList
- <ion-list>
hello world
- avatarList
- <ion-list>
hello world
- thumbnailList
- <ion-list>
hello world
- 支持左滑右滑的列表
- <ion-item-sliding>
test01
关注 删除- actionSheet
- 自地向上 滑出的菜单
- 实现方式
- import {ActionSheetController} from 'ionic-angular'
- constructor(public asCtrl:ActionSheetController){}
- let myActionSheet = this.asCtrl.create({
title:'', buttons:[ { text:'cancel', handler:()=>{}, role:'cancel' },{ text:'删除', role:'destructive', handler:()=>{} },{ text:'分享到朋友圈', handler:()=>{} } ] }) - myActionSheet.present();
- fab
- floating action button
- 实现方式
- <ion-fab>
- loading
- 实现加载中的提示窗口
- 实现方式
- import {LoadingController} from 'ionic-angular'
- constructor(private loadCtrl:LoadingController){}
- let myLoad = this.loadCtrl.create({
content:'', duration:3000 }) - myLoad.present();
- toast
- toast是在无论是android还是iOS原生组件都是由支持的,
为了让ionic项目实现时 更接近与原生的app,ionic封装了实现通知的类:toast - 实现方式
- import {ToastController} from 'ionic-angular'
- constructor(private toastCtrl:ToastController){}
- this.toastCtrl.create({
message:'', duration:1500, position:top/bottom/middle }) - myToast.present();
-
day4
-
grid
-
ionic的grid是基于flexBox
-
基本使用
-
-
- 进阶
- 指定列宽
- <ion-grid>
- 如果一行中的列 都没有指定列的宽度
默认情况:均等分
- 如果一行中的列 指定列的宽度,其余的没有指定列宽的 将均等分剩余的宽度
- 指定列与列之间的偏移量
- <ion-grid>
- 行中列的纵向对齐方式
- <ion-row align-items-start/center/end></ion-row>
- 指定某一列在当前行中的对齐方式
- <ion-col align-self-center/start/end></ion-col>
- 行中各列横向布局方式
- 默认情况,是从左向右
- <ion-row justify-content-start/center/end>
- 调整列距离最左边或者最右边的边界的距离
- //将当前列 设置 向右移动3/12
//将当前列 设置 向左移动3/12
- 刷新
- refresher
下拉刷新
- 步骤1
- 在模板中指定内容:
在ion-content的第一个子元素的位置
- 步骤2
- 绑定事件处理函数
ionRefresh
- <ion-refresher (ionRefresh)="doRefresh($event)">
<ion-refresher-content pullingText="" refreshingText=""
- 步骤3
- 在ionRefresh的处理函数中操作数据
和结束刷新动作
- doRefresh(myRefresher){
//操作数据 //结束刷新动作 myRefresher.complete(); }
- infiniteScroll
上拉加载更多
- 步骤1
- 在模板中指定内容:
在ion-content的最后一个子元素的位置
- 步骤2
- 绑定事件处理函数
ionInfinite
- 在模板中指定内容:
在ion-content的最后一个子元素的位置
<ion-infinite-scroll (ionInfinite)="loadMore($event)"> <ion-infinite-scroll-content loadingText="正在加载数据" loadingSpinner="bubbles/circles/dots"
- 步骤3
- 在ionInfinite的处理函数中操作数据
和结束刷新动作
- loadMore(myInfinite){
//操作数据 //结束刷新动作 myInfinite.complete(); }
- forms
- 在ionic中 实现表单是靠内部实现ionList进行管理的
- 具体组件用法
- 复选框
- <ion-list>
是否同意
- 单选框
- <ion-list radio-group>
北京
上海
广州
- 滑动开关
- <ion-list>
蓝牙
- 下拉菜单
- <ion-list>
选择喜欢的颜色
red
green
- 滑动组件
- <ion-list>
是否同意
0
100
- 输入框
- fixed
- <ion-list>
用户名
- placeholder
- stacked
- <ion-list>
用户名
- floating
- <ion-list>
用户名
- lifecycle
- ionic中每一个页面 都有它自己的生命,会有从创建到消亡的过程
- 具体的生命周期处理函数
- ionViewDidLoad
- ionViewCanEnter
- ionViewWillEnter
- ionViewDidEnter
- ionViewCanLeave
- ionViewWillLeave
- ionViewDidLeave
- ionViewWillUnload
- navigation
- ionic的page之间的跳转其实都是通过navController,
通过一套stack机制的入栈和出栈, 来实现前进和后退的
this.navCtrl.push(Demo02Page) this.navCtrl.pop(); - 跳转
- js
- 步骤1:
import {Demo02Page} from '...' - 步骤2: 跳转
- this.navCtrl.push(Dem02Page);
- 属性
- 步骤1:
import {Demo02Page} from '...' - 步骤2: 在当前的类中 定义一个变量保存Demo02Page
- destinationPage;
constructor(){ this.destinationPage = Demo02Page }
- 步骤3:属性绑定
- <button [navPush]="destinationPage"></button>
- 传参
- 传递参数
- js
- 步骤1:
import {Demo02Page} from '...' - 步骤2: 跳转
- this.navCtrl.push(Dem02Page,{id:10});
- 属性
- 步骤1:
import {Demo02Page} from '...' - 步骤2: 在当前的类中 定义一个变量保存Demo02Page
- destinationPage;
constructor(){ this.destinationPage = Demo02Page }
- 步骤3:属性绑定
- <button
[navParams]="{id:10}" [navPush]="destinationPage">
- 接收参数
- this.navParams.data.id
this.navParams.get('id')
- modal
- modalController可以帮助我们实现一些需要自定义的模态窗,
比如弹出的登录页、支付页面、菜单等 - 使用方式
- import {ModalController} from 'ionic-angular'
- constructor(private modalCtrl:ModalController){
} - 创建模态窗中 要显示的组件或者页面 TestPage - this.modalCtrl.create(TestPage).present();
- slides
- slides允许用户去滑动组件,从而来实现轮播图、新手教程等
- 基本用法
- <ion-slides>
//真正要去显示的内容
- 配置属性
- <ion-slides autoplay="1000" loop="true" effect="fade/slide/cube"
direction="vertical/horizontal" pager paginationType="bullets/fraction/progress" speed="1000"
- tabs
- tabs是用来在移动端的底部 充当导航条作用,可以点击不同的tab页面 切换到指定的不同的页面
- 实现方式
- 创建一个根页面 MyAppPage
- 创建需要显示的其它页面
ProductListPage CartListPage - 在MyAppPage的页面类 中 引入 ProductListPage CartListPage, 定义类中的变量 productList,cartList, 进行赋值: this.productList = ProductListPage; this.cartList = CartListPage - 在MyAppPage这个根页面中指定标签: <ion-tab tab-title="" tab-icon="" hideOnSubPages="true" [root]="productList" > <ion-tab tab-title="" tab-icon="" hideOnSubPages="true" [root]="cartList" >
- localStorage实现数组的读写
- 由于本地存储(localStorage/sessionStorage),
键值对是按照字符串进行存储的,如果说有需求:将数组存在 本地存储中, 要想实现该需求:json序列化和反序列化 ①数组中需要写入数据: 数组是可以存在对象中, 而对象是可以被序列化成一个json格式的字符串, 然后就可以本地存储的
②数组中需要读数据 从本地存储中 得到json格式的字符串, 反序列化得到对象,读取对象中属性就可以得到数组
React
-
day1
-
概述
-
介绍
- React(有时称为React.js 或ReactJS)是一个为数据提供渲染HTML视图的开源JavaScript库
-
历史
- React是由FaceBook的工程师Jordan Walke创建的,是受到php的HTML组件库XHP影响, React在11年时,刚开始是部署在FaceBook的newsfeed; 随后在12年时部署于Instagram,于13年5月在JSConf US宣布开源 14年成为facebook第一个在Github上达到1万star的旗舰开源项目, 15年3月在JSConf,FaceBook发布了React Native,可以使用React来构建nativeApp,并提出自己的理念“learn once,write anywhere”。 16年4月,发布V15正式版本,但是依然不够稳定,这毕竟是最新的技术
-
特点
- 声明式设计:采用声明范式,可以轻松描述应用 高效:通过对DOM的模拟,最大限度减少与DOM的交互 灵活:可以方便的搭配其它库来使用 JSX:是js语法的扩展 组件:构建组件,方便复用 单向相应的数据流
-
核心思想
- 封装组件
-
劣势
- 在你选择之前需要再考虑一下: ①一开始 React 会极大地减慢你的开发。理解props、state以及组件通信如何工作并不是很简单,并且文档信息错综复杂。理论上,这将会被克服,你的整个团队都上道之后,开发速度上就会有一个很大的提升。 ②React 不支持 IE8 以下的任何浏览器,以后也绝不会。 ③如果你的应用/站点不需要频繁的动态页面更新,你可能为了很小的功能而编写大量的代码。 ④你会改造很多轮子。React 很年轻,并且因为没有权威的方式来处理事件、组件通信,你必须从零开始创建大量的组件库。你的应用是否有下拉菜单,可调整大小的窗口,或者 lightbox?你同样必须从零开始写这些。
-
-
搭建React的开发环境
-
引入react.js react-dom.js browser.js 三个js文件
-
demo
-
-
JSX语法
-
基本语法
-
遇到HTML标签(以<开头), 如果首字母是小写的,就用HTML来解析, 如果首字母是大写的,交给React按照组件去解析 遇到代码块(以{开头)就用js来解析
-
demo
-
-
-
组件
-
创建和引用
-
创建
- React 允许将代码封装成组件(component),然后像插入普通 HTML 标签一样,在网页中插入这个组件。React.createClass 方法就用于生成一个组件类
-
-
-
var HelloMsg = React.createClass({ render:function(){ return
TEST
} }) - 引用
- <HelloMsg/>
- 注意事项
- ①组件的名字 首字母必须是大写的,
遵循全驼峰式的命名方式 - ②在render返回要渲染的元素的时候, 第一个html标签 不能直接换行 - ③如果要返回多个元素,要放在一个顶层标签中
- 基本用法demo
-
- 复合组件
-
复合组件:将其他的组件 整合在一起 创建的新组件 积木+积木--》乐高机器人 - demo
-
- props
- 介绍
- 组件的用法与原生的 HTML 标签完全一致,可以任意加入属性,比如 <HelloMsg name="daxu"> ,就是 HelloMsg 组件加入一个 name 属性,值为 daxu。组件的属性可以在组件类的 this.props 对象上获取,比如 name 属性就可以通过 this.props.name 读取
- demo
-
- children
- this.props 对象的属性与组件的属性一一对应,但是有一个例外,就是 this.props.children 属性。它表示组件的所有子节点
- demo
-
- 组件间通信
- 父与子通信
- 父组件中,在调用子组件时,
可以通过属性传值;子组件通过 props对象去获取传递来的数据
- 步骤1:传值
var Parent = React.createClass({ render:function(){ return } }) - 步骤2:接收值 var Son = React.createClass({ render:function(){ return
{this.props.tips}
} }) - 子与父通信
- 步骤1:在父组件定义一个带有参数的方法
var Parent = React.createClass({ rcvMsg:function(arg){ console.log(arg); }, render:function(){ return } }) - 步骤2:将父组件中的方法 传递给子组件 var Parent = React.createClass({ rcvMsg:function(arg){ console.log(arg); }, render:function(){ return } }) - 通过props去读取父组件传来的方法, 调用并完成传值 var Son = React.createClass({ sonName:'zhangsan', handleClick:function(){ this.props.funcRcv(this.sonName); }, render:function(){ return clickMe } })
- 兄弟通信
- 兄弟组件 有一个共同的父组件;
兄弟组件间通信方式 是依赖于共同的父组件; 把需要共享的数据放在父组件
- refs
- 介绍
- 组件并不是真实的 DOM 节点,而是存在于内存之中的一种数据结构,叫做虚拟 DOM (virtual DOM)。只有当它插入文档以后,才会变成真实的 DOM 。根据 React 的设计,所有的 DOM 变动,都先在虚拟 DOM 上发生,然后再将实际发生变动的部分,反映在真实 DOM上,这种算法叫做 DOM diff ,它可以极大提高网页的性能表现
但是,有时需要从组件获取真实 DOM 的节点,这时就要用到 ref 属性
- demo
-
- react编程风格推荐
- 推荐1
- 方法顺序遵循生命周期放在前面, render() 方法放在最后
- 推荐2
- 事件处理函数的命名
采用 "handle" + "EventName" 的方式来命名
- 推荐3
- 事件函数作为属性时的命名
为了跟 react 的事件命名保持一致: onClick, onDrag, onChange, 等等,采用如下格式:
- 推荐4
- 元素跟 return 放在同一行
为了节约空间,采用下面的写法:
return
-
day2
-
state
-
3个基本操作
-
初始化
- getInitialState:function(){ return {opacityValue:0} }
-
读写
- this.state.opacityValue
- this.setState({opacityValue:0.1},function(){ //状态设置成功之后的处理函数 })
-
-
作用
- 将状态中的数据 绑定 到视图
-
-
{this.state.btnState?'开':'关'}
- lifecycle
- 组件的生命周期在React主要
分为3个阶段:mount/update/unmount - 处理函数
- componentWillMount
- componentDidMount
- componentWillReceiveProps
- componentWillUpdate
- componentDidUpdate
- componentWillUnmount
- 注意事项
- 如果要想通过ref去定位元素进行操作,
那么必须等到componentDidMount - componentWill/DidUpdate(props,state) props或者state有变化的时候,才会调用和更新相关 的处理函数
- 表单受控元素
- input指定了value,
select指定了selected checkbox指定了checked 是一个表单受控元素 - 解决方案
- ①初始化状态
- ②将状态中的值 绑定给表单元素
- ③在onChange中 修改状态中的值
-
day3
-
todobox
-
组件的创建和使用
-
父与子通信
- todobox 有一个状态myList,通过属性传递给了todolist ...
-
子与父通信
- todoinput和todoitem点击add、delete按钮时 要去操作todobox中状态对应的数组
-
状态state
-
getInitialState:function(){ return myList:[] }
-
add/delete
- this.setState({myList:[]})
-
-
-
三连棋
- 在React编码中,虽然支持在js中 直接去编写html标签,但是jsx的语法毕竟是一个需要转换为 浏览器能够识别的语法,html标签不能像之前一样随便写: style={{opacity:1}}
-
- 三个组件 Square/Board/Game
- Board组件中涉及到state的读、初始化、设置
- Square组件按钮单击时,要设置board组件中的状态(子与父通信)
- Square组件要想显示x或者o,将board组件中状态对应的数组 传递给Square(父与子通信)
- ReactNative概述
- RN是一个实现nativeApp的框架,
采用是React的核心思想(一切都是组件) 和核心概念(jsx/state/props/refs/component), 开发理念:learn once,write anywhere
当前所学习的版本:0.49 - why
- 开源免费
- 开发成本低(学习成本、时间成本)
- 可以真正的实现nativeapp的开发(相比hybrid/webApp运行更流畅)
- how
- 方式1
- create-react-native
- 方式2(建议)
- react-native-cli
- ReactNative基础使用
- 开发时工作原理
- react-native start
- 启动了一个模拟器,安装一个myapp的apk结尾的文件,
然后设置开发服务器的ip和端口号
- RN中的组件的使用
- 注意事项:
①在写ReactNative组件时候,返回的必须是ReactNative封装好的组件, 不能是div/p/ul/table... ②StyleSheet 属性的设置 都支持通过style去指定,如果自己创建的样式类,属性名必须是驼峰式 - View
- 指定一个容器
- Text
- 指定一段文本内容
- StyleSheet
- 指定样式
- import {StyleSheet} from 'react-native';
- const myStyle = StyleSheet.create({
myRed:{ color:'red', fontSize:20 } }) -
-
day4
-
View
- 指定一个容器
-
Text
- 指定一段文本内容
-
StyleSheet
-
指定样式
- import {StyleSheet} from 'react-native';
- const myStyle = StyleSheet.create({ myRed:{ color:'red', fontSize:20 } })
-
-
Button
-
State
-
3个基本操作
-
初始化
- constructor(){ super(); this.state = { count:0 }; }
-
读
- this.state.count
-
写
- this.setState({count:1})
-
-
-
TextInput
- <TextInput placeholder="plz input sth" onChangeText={(data)=>{}}/>
-
Image
-
本地资源文件
- <Image source={require('./img/1.jpg')}/>
-
网络资源文件
- <Image source={{uri:'*****'}}/>
-
-
TouchabelOpacity
- 给任何一个元素 添加 点按时透明度变化的效果
hello world
-
fetch
-
fetch是由ReactNative所封装的一个处理与远程服务器端通信 的方法
-
使用方式
- fetch(url,{method:'get/post'}) .then((response)=>response.json()) .then((response)=>{ //response就是服务器端返回的结果 })
-
-
FlatList
-
是由RN所封装一个高性能的列表
-
使用方式
- <FlatList renderItem={(info)=>{ return {info.index} }} data={this.list}/>
-
-
keyboardAvoidingView
-
避免在进行表单操作时候,表单元素被弹出的键盘遮住的问题
-
如何使用?
- 在表单元素上层套一个容器keyboardAvoidingView
-
-
switch
- 滑动开关
-
ActivityIndicator
- loading 加载中的效果
-
导航
-
借助于ReactNavigation开源项目, 内部又细分为3个导航模式, 比如stackNavigator/tabNavigator/drawerNavigator
-
stackNavigator
- ①安装reactNavigation
-
-
npm install react-navigation - ②创建页面需要用到的各个组件,比如 ListComponent DetailComponent - ③配置路由词典 import {StackNavigator} from 'react-navigation'
const myRouter = StackNavigator({ myList:{ screen:ListComponent }, myDetail:{ screen:DetailComponent } })
AppRegistery.register( ()=>myRouter)
- ④跳转到myDetail
this.props.navigation.navigate("myDetail")