移动App第3天
复习
-
为什么要学习webpack,对一些语法糖高级语法进行解析降档
-
能够说出Webpack的作用
- 他是一款前端的开发构建工具,能够对高级语法进行解析降档,能够进行打包压缩等等处理操作
-
能够说出webpack打包时loader加载的原理
- 找到js文件,识别js文件中是否有webpack不认识的语法,如果有,就会去找合适的loader
- 如果找到了相关的loader,就直接处理
- 如果没找到,报错
- babel bableloader bable-core 字典 es2015 stage-0 plugin tranform runtime
-
能够使用开发时候的webpack配置文件
-
掌握webpack-dev-server的使用
-
掌握html-webpack-plugin的使用
-
-
了解什么是webpack的发布策略
- 写一个单独的发布的配置文件
- 通过webpack --config 配置文件名称
- 配置文件中,删除开发相关的配置项,加入一些发布相关配置项
-
了解常见插件的使用
什么是React
- facebook 在开发大型网站时发现一些问题 直接使用HTML,js ,css, 网站健壮性差,不利于维护,复用性差
- 当时angular.js 1.x react
- 2013年5月份facebook将react开源
- vue 2014年, 2016 2.0版本
- angular.js, vue.js, react.js
React与vue.js的对比
- 首先,这两个框架,都是以组件化的思想进行开发的!
- 什么是模块化:模块化就是将一个程序按照功能进行拆分,分成相互独立的模块,以便每个模块只包含与其功能相关的内容。
- 针对功能方面进行拆分, 每个模块只包含与其功能相关的内容
- 什么是组件化:组件化就是基于可重用的目的,将一个大的软件系统按照分离关注点的形式,拆分成多个独立的部分,每个独立的部分称之为一个组件。
- 从UI的方面进行功能的拆分
- 粒度:模块化要比组件化的粒度更细
- 从社区的角度去看两个框架:
- 因为react他的时间更长,社区相对会更加丰富
- 从开发者的角度去看两个框架:
- facebook 技术实力雄厚 不会出现断更的情况一直更新
- vue 由尤雨溪开发 现在也有一个开源团队去进行维护
- 从开发的角度去进行对比
- vue:.vue文件
- template: 模板文件,相当于html
- script: 逻辑部分, 相当于js
- style: 样式部分,相当于css
- react:
- 没有给我们提供类似vue的.vue文件
- 而是直接使用js进行开发
- vue:.vue文件
为什么要学习React
- React社区强大,不会出现突然断更的情况!
- 开发团队给力,技术雄厚!
- 可以转到ReactNative上进行移动App开发体验!
- React非常适合大型项目的开发,项目越大,React的优势体现的也就越明显!
React中几个核心的概念
- 虚拟DOM(Document Object Model)
- 为什么要实现虚拟DOM:因为浏览器中默认实现DOM更新的方式速度很慢,效率地下,所以需要通过自己实现虚拟DOM,来提高DOM更新效率!
- 什么是React中的虚拟DOM:就是利用JS对象的形式,来模拟一颗真正的DOM树。
- 虚拟DOM的目的:提高DOM的渲染效率!
- Diff算法
- tree diff: 将新旧两颗DOM树,相同的层级节点,从上到下,逐层进行对比的过程,叫做tree diff。好处:对比次数少,当把整个DOM树每一层梳理完成之后,则就找到了需要更改的元素!
- component diff:在对比每一层的时候,对每一层中的组件进行对比,如果组件类型相同,则暂时认为不需要修改,如果类型不相同,则删除旧组件,创建新组建,将新组建替换到旧组件的位置!
- element diff:当组件类型相同的时候,需要对组件中的每一个元素进行对比,这种对比方式,叫做element Diff。
- 在通过for循环,循环创建类型相同的组件或者元素的时候,最好为每一个创建的东西,添加一个唯一的
key
值,这样能提高我们虚拟DOM的对比效率!
React项目的创建
- 运行
cnpm i react react-dom --save
安装react依赖包 - 导入相关模块:
// react这个模块,是专门用来创建虚拟DOM元素,或者创建React组件,包括组件的生命周期等一系列和虚拟DOM相关的东西,都在这个模块中进行定义
import React from 'react'
// react-dom这个模块,是帮我们进行DOM操作的模块,比如说:将创建好的虚拟DOM元素,挂在到页面指定的容器中,就是通过这个模块进行实现的
import ReactDOM from 'react-dom'
- 使用
React.createElement
来创建虚拟DOM: // React.createElement方法中,参数列表的含义: // 第一个参数:用字符串,指定要创建的元素的类型 // 第二个参数:用对象,指定要创建的元素的相关属性 // 第三个参数:any,指定要创建的元素的子节点 // 从第三个参数开始,都是当前创建元素的子节点!!!
// 创建一个div元素,这是属性,同时设置两个子节点
var divObj = React.createElement('div', {id:'div1', title:'this is a div'}, '彬哥好帅啊,崔刚老师更帅!', h1Obj);
- 使用
ReactDOM.render
渲染虚拟DOM:
ReactDOM.render(divObj , document.getElementById('app'));
JSX语法
-
在JSX语法中,出现 {} 的时候,就表示说,我们要在 {} 内部,写JS语法了!
-
只要是符合JS语法规范的,都可以向 {} 书写!
-
在JSX语法中,如果想给元素添加类样式,需要用 className 来代替 class ,因为 class 是ES6中的关键字!
-
与 className 类似,label的 for 属性也是一个JS关键字,需要用 htmlFor 来代替!
-
使用JSX语法必须要配置webpack的loader,使用babel-loader去解析JSX语法
-
安装babel-loader的命令中需要新增一个babel-preset-react
-
整个安装命令:
- cnpm i babel-core babel-loader babel-plugin-transform-runtime --save-dev
- cnpm i babel-preset-es2015 babel-preset-stage-0 babel-preset-react --save-dev
-
.babelrc文件
-
{ "presets":["es2015","stage-0","react"], "plugins":["transform-runtime"] }
-
React中:第一种创建组件的方式
第一种基本组件的创建方式
- 使用构造函数的形式,来创建一个React中最基本的组件,名字叫做Hello
- 怎么使用自定义组件:以标签的形式,将组件引用到需要的地方即可!
- 在构造函数创建的组件中,必须return一个元素或者一个null,否则,会报错!
function Hello(){
return <div>
{/*这是一个注释,你肯定看不到我,因为我是注释*/}
<br/>
这是一个Hello组件
</div>;
}
- 以标签的形式去引用组件:
<Hello name="zs" age={20} gender="男"></Hello>
父组件向子组件传递数据
- 通过属性的方式,向组件中传递数据:
<Hello name="zs" age={20} gender="男"></Hello>
- 在构造函数创建的组件中,如何获取到传递进来的数据,使用参数列表中的
props
来接收:(想要在页面上显示props属性,需要安装一个chrome插件,React Developer Tools)
function Hello(props){
return <div>
这是一个Hello组件----- {props.name} ---- {props.age} ---- {props.gender}
</div>;
}
将组件封装到单独的文件中
// 注意:必须导入react模块,否则会报错
import React from 'react'
function Hello2(){
return <div>
这是一个Hello2组件
</div>;
}
export default Hello2
React中:第二种创建组件的方式
了解ES6中class关键字的使用
基于class关键字创建组件
- 使用 class 关键字来创建组件
class Person extends React.Component{
// 通过报错提示得知:在class创建的组件中,必须定义一个render函数
render(){
// 在render函数中,必须返回一个null或者符合规范的虚拟DOM元素
return <div>
<h1>这是用 class 关键字创建的组件!</h1>
</div>;
}
}
两种创建组件方式的对比
- 用构造函数创建出来的组件:专业的名字叫做“无状态组件”
- 用class关键字创建出来的组件:专业的名字叫做“有状态组件”
用构造函数创建出来的组件,和用class创建出来的组件,这两种不同的组件之间的本质区别就是:有无state属性!!! 有状态组件和无状态组件之间的本质区别就是:有无state属性!
一个小案例,巩固有状态组件和无状态组件的使用
通过for循环生成多个组件
- 数据:
CommentList = [
{ user: '张三', content: '哈哈,沙发' },
{ user: '张三2', content: '哈哈,板凳' },
{ user: '张三3', content: '哈哈,凉席' },
{ user: '张三4', content: '哈哈,砖头' },
{ user: '张三5', content: '哈哈,楼下山炮' }
]
- 属性扩散:
- 使用{...item}的方式能够将item对象中的所有元素,以属性的方式传递到应用这个语法的组件上
style样式
总结
理解React中虚拟DOM的概念 理解React中三种Diff算法的概念 使用JS中createElement的方式创建虚拟DOM 使用ReactDOM.render方法 使用JSX语法并理解其本质 掌握创建组件的两种方式 理解有状态组件和无状态组件的本质区别 理解props和state的区别
相关文章
移动App第4天
复习
-
虚拟DOM和Diff算法:提高组件的渲染效率
- treeDiff: 按照层的概念去进行比较
- componentDiff : 比较每个组件
- elementDiff: 比较每个组件中的元素
-
创建虚拟DOM的两种方式:
- npm i react react-dom --save
- react: 用来创建虚拟DOM
- react-dom: 用来操作虚拟DOM
- react.createElement('div', {name:'',id:''}, '内容',...children)
- JSX语法:js的可扩展标记语言,它允许我们在js文件中使用html标签去创建虚拟DOM
- 注释和js代码必须用{}包裹
- class是js的关键字要使用className替代
- for也是js的关键字要使用htmlFor去替代
- reactDom.render(VDom, Dom, callback)
-
两种组件创建的方式:
- 使用构造函数的方式创建组件:在方法体内必须要return一个null或者是一个虚拟DOM对象:【无状态组件】props只读的
- 使用es6中的class关键字去创建一个组件:extends react.component,render(){return null/dom}:【有状态组件】props只读的,state 表示组件的状态,可读可写
-
使用style添加样式:
- style:jsx语法中不能直接接收字符串,必须接收数据对象{ {border: '1px solid red'} }
-
属性扩散:
- { ...item }
-
组件从创建、到加载到页面上运行,再到页面关闭组件被销毁,这期间总是伴随着各种各样的事件,那么这些事件,统称为组件生命周期!
组件的生命周期
- Vue组件的生命周期
- 组件生命周期分为三部分:
- 组件的创建阶段:里面的所有事件都有一个共同点,只执行一次
- setState:componentWillMount,componentDidMount
- 组件的运行阶段:里面所有的事件也有一个共同点,执行0-N次
- setState:componentWillReceiveProps
- 组件的销毁阶段:执行1次
- 组件的创建阶段:里面的所有事件都有一个共同点,只执行一次
getDefaultProps
在组件创建之前,会先调用 getDefaultProps(),这是全局调用一次,严格地来说,这不是组件的生命周期的一部分。在组件被创建并加载候,首先调用 getInitialState(),来初始化组件的状态。
React生命周期的回调函数总结成表格如下:
组件生命周期的执行顺序:
- Mounting:
-
constructor()
-
componentWillMount()
-
render()
-
componentDidMount()
- Updating:
-
componentWillReceiveProps(nextProps)
-
shouldComponentUpdate(nextProps, nextState)
-
componentWillUpdate(nextProps, nextState)
-
render()
-
componentDidUpdate(prevProps, prevState)
- Unmounting:
- componentWillUnmount()
通过Counter计数器的小案例 - 了解生命周期函数
- 给组件设置默认属性:
// getDefaultProps方法在es6中已经弃用
// 使用下面的方式进行props的初始化
static defaultProps = {
count: 0
}
- 给属性进行类型校验
// 用来进行属性校验,PropsTypes里面提供了很多的数据类型,但是页面上照常显示,只是在开发过程中给出了错误提示
// 1. npm i prop-types --save
// 2. import PropTypes from 'prop-types'
static propTypes = {
count: PropTypes.number
}
组件初始化时生命周期事件总结
- componentWillMount:组件还没创建 可以使用setState
- render:组件渲染创建阶段
- componentDidMount:组件已经挂载到页面上 可以使用setState
- 注意:在render函数中,不能调用
setState()
方法:
// 在render方法中,可以使用setState方法,但是setState方法会触发组件重新渲染,重新调用render方法死循环
// this.setState({
// count: 1
// })
通过原生的方式获取元素并绑定事件
// 使用原生的方式设置点击事件
// document.getElementById('btn').onclick = () => {·
// this.setState({
// count: this.state.count + 1
// })
// }
使用React中的事件,绑定count自增
- 给按钮绑定
onClick
事件:
<input type="button" value="日本又死人了,柯南要破案了" onClick={ this.onclick } />
- 使用箭头函数,创建一个事件响应函数:
onclick = ()=> {
console.log('点击事件');
// 如果不用箭头函数的方式,这里获取的this是null
// 不是原生js点击事件里面获取的对象
console.log(this);
this.setState({
count: this.state.count + 1
})
}
React中使用ref属性获取DOM元素引用
- 给DOM元素添加
ref
属性:
<div ref='div1'>小五郎脖子上扎了{this.state.count}针</div>
- 通过组件的
this.refs
来获取对应的引用:
console.log('shouldComponentUpdate---' + this.refs.div1.innerHTML);
组件运行中事件的对比
- shouldComponentUpdate: 这个方法里面获取的state对象和页面上的元素都是更新之前的
// 组件是否应该已经新
// 这个方法有返回值,必须是bool类型的值
// 如果是false说明要阻断组件的更新
// 如果是true 组件更新
// 里面使用this.state方式获取的state对象是更新之前的
// 如果要使用最新的,使用参数的形式进行获取
shouldComponentUpdate(nextProps, nextState) {
console.log('shouldComponentUpdate---' + this.refs.div1.innerHTML);
// console.log(this.state.count + ' ------------- ' + nextState.count);
// if(nextState.count % 2 === 0){
// return true;
// }
return true;
}
- componentWillUpdate:这个方法里面获取的state对象和页面上的元素都是更新之前的
- render:页面上的元素都是更新之前的
- componentDidUpdate: 获取的state和页面上的元素都是最新的
绑定this并传参的三种方式
- 在事件中绑定this并传参:
<input type="button" value="在事件中绑定this并传参" onClick={ this.click.bind(this, 'aa', 'bb') }/>
- 在构造函数中绑定this并传参:
constructor(){
super();
this.state = {
msg:''
}
// 先使用bind方法将this和参数绑定上去,再将绑定之后的方法对象赋值到了click1上
this.click1 = this.click1.bind(this, 'bb', 'cc');
}
<input type="button" value="在构造函数中绑定this并传参" onClick={ this.click1 }/>
- 用箭头函数绑定this并传参:
<input type="button" value="使用箭头函数中绑定this并传参" onClick={ ()=>{ this.click2('cc', 'dd') } }/>
绑定文本框与state中的值
- 在Vue.js中,默认可以通过
v-model
指令,将表单控件和我们的data
上面的属性进行双向数据绑定,数据变化和页面之间的变化是同步的! - 在React.js中,默认没有提供双向数据绑定这一功能,默认的,只能把
state
之上的数据同步到界面的控件上,但是不能默认实现把界面上数据的改变,同步到state
之上,需要程序员手动调用相关的事件,来进行逆向的数据传输! - 绑定文本框和state的值:
<input ref="text" type="text" value={ this.state.msg } onChange={ this.changeText }/>
changeText=(e)=>{
// console.log(e.target.value);
// setState方法执行更新state的时候,是一个异步的操作,不能够直接获取到最新的state值
// setState方法允许我们传入一个回调函数,在回调函数中能够获取到最新的state
this.setState({
msg: e.target.value
}, function(){
console.log(this.state.msg);
})
console.log(this.state.msg);
}
- 注意
setState的一个问题
:setState是异步的
// setState方法执行更新state的时候,是一个异步的操作,不能够直接获取到最新的state值
// setState方法允许我们传入一个回调函数,在回调函数中能够获取到最新的state
this.setState({
msg: e.target.value
}, function(){
console.log(this.state.msg);
})
console.log(this.state.msg);
发表评论案例
扩展
Context:上下文环境
用于父组件向子组件传递数据
使用步骤:
-
在父组件中调用getChildContext方法获取子组件上下文并返回数据:
// 给所有的子组件去共享数据使用context getChildContext(){ return { color: this.state.color } }
-
在父组件中使用childContextTypes对数据进行校验:
// 给子组件通过Context共享数据,必须要进行类型验证 // 使用下面的方式: 验证需要安装 prop-types static childContextTypes = { color: PropTypes.string }
-
在子组件中使用contextTypes对数据进行校验:
// 子组件想要接收父组件通过COntext传递的数据,还要进行类型验证 static contextTypes = { color: PropTypes.string }
相关文章
类型校验
移动App第5天-豆瓣电影
复习
-
了解组件生命周期的三个阶段
- 组件的创建阶段:所有的方法只执行一次,
- 初始化属性props:static defaultProps = {}
- 初始化state:在构造函数中通过 this.state = {}
- 使用setState方法:
- willMount
- didMount
- 组件的运行阶段:执行0-N次
- 使用setState:willReceiveProps
- 组件的销毁阶段:执行1次
- 组件的创建阶段:所有的方法只执行一次,
-
掌握defaultProps和propTypes的使用
-
掌握React提供的事件绑定机制
- 第一种:获取原生的DOM对象,使用原生方式进行事件绑定
- 第二种:JSX语法属性绑定 onClick
-
掌握ref的形式获取元素
- 在JSX语法的标签上,设置ref属性
- this.refs.属性值
-
了解绑定this并传参的三种方式
- call apply bind
- 使用bind方法,在事件中绑定this并传参 方法名.bind(this, '','')
- 在构造函数中绑定this,构造函数里:方法名 = 方法名称.bind(this,'','')
- 使用箭头函数:拉姆达表达式,lambda就是箭头函数
-
掌握表单控件配合onChange事件使用
- value={this.state.msg} , 表单变成了受控表单,无法操作
- onChange = { this.setState({ msg: --------- }) }
-
父组件向子组件传值
- 直接使用属性的方式,属性扩散的方式进行传值:this.props
- Context getChildContext(){ return { color:'red' }} static childContextTypes={} 子组件 contextTypes = {} this.context.color
-
了解子组件向父组件传值
- 可以通过props的方式传递一个方法,方法里面可以传参
- this.props.父组件传递过来时使用的属性名称()
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规范
- 定义:就是一个异步的代码规范;
- 好处:
- 更好的帮我们解决回调地狱问题
- 能帮我们很好的实现代码的复用
基于Promise规范的fetch API的使用
项目需求分析:
-
页面的结构: Ant Design
-
点击导航切换显示内容: 使用路由
-
数据来源:豆瓣电影的API
-
获取数据:Ajax fetch
-
点击返回返回上一个页面
项目结构搭建和布局
实现ANT组件的按需加载
使用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
渲染电影列表
相关文章
- 跨域资源共享 CORS 详解 - 阮一峰
- Request - Simplified HTTP client
- CSS3 transform 属性
- ES6 - Promise规范 - 阮一峰
- 刘龙彬 - 博客园 - Javascript中Promise的简单使用
- Javascript 中的神器——Promise
- MDN - Fetch API
- MDN - Response
React第6天
复习:
- Promise对象用来解决回调地狱 new Promise
- ant design 基于React的前端UI框架
- request http请求客户端
- fetch Api fetch(url).then(function( response ){ response.json().then(function(data){ data最终想要的数据 }) })
- 路由 react-router: BrowserRouter Route Link Redirect
一、 配置ReactNative基本开发环境
搭建基本的开发环境 - 英文官网<br/> 搭建基本的开发环境 - 中文 这两篇文档对比着进行参考,进行相关的安装;
二、 搭建RN的项目
- 运行
react-native init 项目名称
来初始化一个react native项目; - 打包运行项目,把打包好的项目部署到手机中!
- 确保手机已经正确的链接到了当前电脑上,同时手机开启了
开发者调试模式
;可以使用adb devices
来查看当前链接到电脑上的手机设备列表! - 当确认手机正确链接到电脑上之后,可以运行
react-native run-android
来打包当前项目,并把打包好的项目以调试的模式安装到手机中! - 打包完成之后的截图
- React Package窗口的作用
- 04.React Packager打包编译代码
- 当第一打包编译项目部署到手机上之后 - 如何设置开发服务器的地址 ![05.当第一打包编译项目部署到手机上之后 - 如何设置开发服务器的地址.png](images/05.当第一打包编译项目部署到手机上之后 - 如何设置开发服务器的地址.png)
三、 项目结构介绍以及打包运行的一些注意事项
四、 使用样式
五、 基本组件的使用介绍
- View:
- Text:
- TextInput:
- Image:
- 引用本地资源文件,使用
require(相对路径)
:
<Image source={require('./images/1.jpg')}></Image>
- 引用网络上的资源时候,必须预先指定图片的宽高:
<Image source={{uri:'http://www.itcast.cn/images/slidead/BEIJING/2017332909331100.jpg'}} style={{width:200, height:200}}></Image>
- Button:
- ActivityIndicator:
- ScrollView:用法简单,只需要把要滚动的内容,放到ScrollView容器中即可实现滚动!
- ListView:ListView组件必须的两个属性是dataSource和renderRow。dataSource是列表的数据源,而renderRow则逐个解析数据源中的数据,然后返回一个设定好格式的组件来渲染。
// 使用方式:
// 1. 创建一个ListView的数据源对象,配置对象是一个固定写法, 作用是为了实现ListView组件的高效更新
// 将来,这个数据源对象,会交给ListView去展示,目前,刚创建完毕的数据源,是个空数据源
const ds = new ListView.DataSource({ rowHasChanged: (r1, r2) => r1 !== r2 });
this.state = {
// 调用数据源对象的cloneWithRows方法,将数据交给数据源去保存
userList: ds.cloneWithRows(['柯南', '毛利', '嬴政', '里斯', '毛多多', '柯南', '毛利', '嬴政', '里斯', '毛多多', '柯南', '毛利', '嬴政', '里斯', '毛多多'])
}
<ListView
dataSource={this.state.userList}
renderRow={(rowData) => <Text>{rowData}</Text>}
/>
六、 案例:豆瓣电影列表
- 电影列表数据:
https://api.douban.com/v2/movie/in_theaters
- 电影详细数据:
https://api.douban.com/v2/movie/subject/26309788
七、 安装路由
- 运行
npm i react-native-router-flux@3.38.0 --save
- 路由官网:
https://github.com/aksonov/react-native-router-flux
- 路由相关配置:
https://github.com/aksonov/react-native-router-flux/blob/master/docs/API_CONFIGURATION.md
- 路由简单的DEMO:
https://github.com/aksonov/react-native-router-flux/blob/master/docs/MINI_TUTORIAL.md
八、 路由的一些基本使用方法
九、 配置首页的轮播图
- 轮播图官网:
https://github.com/leecade/react-native-swiper?utm_source=tuicool&utm_medium=referral
- 运行
npm i react-native-swiper --save
安装轮播图组件 - 导入轮播图组件
import Swiper from 'react-native-swiper';
- 其中,在Swiper身上,
showsPagination={false}
是用来控制页码的;showsButtons={false}
是用来控制左右箭头显示与隐藏;height={160}
是用来控制轮播图区域的高度的! - 设置轮播图的样式:
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%'
}
})
- 将组件的代码结构引入到页面上:
<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官网
-
安装插件
npm install react-native-image-picker@latest --save
-
修改android/build.gradle文件
buildscript { ... dependencies { classpath 'com.android.tools.build:gradle:2.2.+' // <- USE 2.2.+ version } ... } ...
-
修改android/gradle/wrapper/gradle-wrapper.properties文件
distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-all.zip
-
修改android/app/build.gradle
dependencies { compile project(':react-native-image-picker') }
-
修改AndroidManifest.xml
<uses-permission android:name="android.permission.CAMERA" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
-
修改MainApplication.java
import com.imagepicker.ImagePickerPackage; // <-- add this import public class MainApplication extends Application implements ReactApplication { @Override protected List<ReactPackage> getPackages() { return Arrays.<ReactPackage>asList( new MainReactPackage(), new ImagePickerPackage() // <-- add this line // OR if you want to customize dialog style new ImagePickerPackage(R.style.my_dialog_style) ); } }
-
在我们自己的组件中添加如下代码:
// 第1步:
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步:
<Button title="拍照" onPress={this.cameraAction}></Button>
<Image source={{ uri: this.state.imgURL }} style={{ width: 200, height: 200 }}></Image>
// 第4步:
cameraAction = () => {
ImagePicker.showImagePicker(photoOptions, (response) => {
console.log('response' + response);
this.setState({
imgURL: response.uri
});
if (response.didCancel) {
return
}
})
}
一定要退出之前调试的App,并重新运行react-native run-android
进行打包部署;这次打包期间会下载一些jar的包,需要耐心等待!
相关文章
- React Native 小米(红米)手机安装失败、白屏 Failed to establish session 解决方案
- React Native Android 初次试用遇到的各种坑
- Redux 中文文档
- weex
- electron
- RN正式打包