一、页面设置、wxml、wxss和flex布局、rpx
项目包含知识
重要知识:模板,自定义组件,自行学习
app.json的页面中只能是相对路径
配置顶部文字,背景
//about.json
{
"navigationBarBackgroundColor": "#fff",
"navigationBarTitleText": "豆瓣电影",
"navigationBarTextStyle":"black",
"backgroundTextStyle":"light"
}
【问题】动态获取页面标题
wmxl组件的属性
<text class="info"
id="abc"
style="color:red"
hidden=""
data-user-name="user">liujie</text>
//通过data-设置的属性会在事件触发时封装在事件对象中传递
多个元素放置在一个放置到一个容器中,以便对多个元素进行样式控制
wxss样式
页面布局三大目标
从上到下
相对均匀分布
水平居中
传统实现方式,以及其问题
/* pages/about/about.wxss */
.mycontainer{
background-color: green;
height:100vh;
/* 2水平居中 */
text-align: center;/*控制其容器内子元素水平居中*/
}
/*1水平放置*/
text{
display: block;
}
/* 3竖直方向等间距 */
image,text{
margin-bottom:60px;
}
问题:样式有的定义在父级元素上,有的定义子元素上;且严重依赖页面具体像素大小;
行级元素变为块级元素
text{
display: inline/block;
}
基于flexbox layout的实现(弹性盒子)
首先找到弹性盒子的容器元素,首先要将其变成一个弹性盒子
display:flex;
.mycontainer{
background-color: green;
height:100vh;
display:flex;
/* 1主轴方向从上往下*/
flex-direction: column;
/* 2从上往下等间隔 */
justify-content:space-around;
/* 3水平居中 */
align-items: center;
}
实现的是一个整体布局,可拓展性较高
【易错】margin多个元素并列写不需要逗号
margin:0 20rpx;//正确
margin:0,20rpx//错误
响应式长度单位rpx
让元素的大小适应不同的设备
UI效果图,视觉设计稿通常使用iphone6来做,iphone实际宽度为375px,相对于小程序750rpx,换算比例为1:2;
让图片宽高保持为屏幕一半大小
.about-banner{
width: 375rpx;
height: 375rpx;
border-radius:50%;//图片设置为圆角
}
单个元素样式,可采用直接在元素中设置
<text style="font-weight:bold;font-size:60rpx">电影周周看</text>
二、app.wxss公共样式表、navigator、tabBar、顶部导航栏样式
weekly页面,每一个用户可访问页面都需要在app.json中注册
app.wxss全局样式表
//app.wxss
.mycontainer{
background-color: green;
height:100vh;
display:flex;
/* 1主轴方向从上往下*/
flex-direction: column;
/* 2从上往下等间隔 */
justify-content:space-around;
/* 3水平居中 */
align-items: center;
}
配置weekly页面标题,weekly.json
navagator组件
组件中包含的元素只能是纯文本,其他非文本的内容都会被忽略掉。
<view class='mycontainer'>
<image class="about-banner" src="/images/1.jpg"></image>
<text style="font-weight:bold;font-size:60rpx">电影周周看</text>
<view>
<text>我</text>
<navigator style="display:inline" url="/pages/weekly/weekly">每周推荐</navigator>
<text>一部好片</text>
</view>
<text>我的微博:weibo.com/liujie</text>
</view>
由于mycontainer样式的设计,最外层view的子元素会分行,需要将navigator及其两个元素放在一行,需要再用一个view进行封装。
navigator默认是块级元素,需设置为inline元素
open-type属性
open-type="navigate"//默认可返回
open-type="redirect"//不可返回
hover-class属性——点击态样式效果
.nav-default{
color:blue;
}
.nav-hover{
color:red;
}
<navigator style="display:inline" url="/pages/weekly/weekly" open-type="navigate" class="nav-default" hover-class="nav-hover">每周推荐</navigator>
//样式谁在后面定义,谁胜出,navigate通过inline设置颜色,点击态颜色无效。
tabBar底部标签栏
tabBar本质是对若干一级入口的链接
tabBar代码
"tabBar": {
"list": [
{
"text": "每周推荐",
"pagePath": "pages/weekly/weekly",
"iconPath": "images/icons/weekly.png",
"selectedIconPath": "images/icons/weekly-selected.png"
},
{
"text": "关于",
"pagePath": "pages/about/about",
"iconPath": "images/icons/about.png",
"selectedIconPath": "images/icons/about-selected.png"
}
],
"color": "#000",
"selectedColor": "#00f"
},
原来navigator链接无效处理
在app.json中配置了weekly对应的tabBar,
当在about中点击navigator链接,希望:跳转到链接页面+同时Tabbar也要切换。
此时open-type取值应该是“switchTab”
<navigator style="display:inline" url="/pages/weekly/weekly" open-type="switchTab" class="nav-default" hover-class="nav-hover">每周推荐</navigator>
全局顶部导航栏样式
//app.json 一次全局配置所有页面颜色,但是各个页面可自行配置,覆盖全局配置
"window": {
"navigationBarBackgroundColor": "#fff",
"navigationBarTitleText": "小程序名称", //每个页面默认标题
"navigationBarTextStyle": "black",
"backgroundTextStyle": "light"
},
三、数据绑定、条件渲染、列表渲染、swiper轮播图
数据绑定
about页面视图中的数据可以硬编码,weekly页面的数据信息需要根据服务器返回数据渲染更新
传统方法:在页面加载过程中,通过一个ajax调用来请求server返回本周推荐电影的详细信息,然后收到一个javascript对象,改变html相应位置
更新视图的代码与视图关系耦合太严重。
理想方式:让视图中的每一个部分与数据做一个映射,然后开发者就只需要关注如何获取数据以及对数据进行更新。
框架需要自动的根据更新的数据对视图进行渲染更新
小程序中使用page中的data属性存储数据(页面数据)
页面内部状态变量thisWeekMovie
/**
* 页面的初始数据
*/
data: {
thisWeekMovie:{
name:"教父",
comment:"最精彩的剧本,最真实的黑帮电影",
imagePath:"/images/10.jpg"
},
count:123
},
数据绑定到视图输出显示
对内部状态数据变量直接进行数据绑定
<view class='mycontainer'>
<text>本周推荐</text>
<image class="about-banner" src="{{thisWeekMovie.imagePath}}"></image>
<text>{{thisWeekMovie.name}}</text>
<text>{{thisWeekMovie.comment}}</text>
</view>
内部状态变量,运算组合,数据绑定
<text>{{count+score}}</text> //表达式
<text>{{score>=60? "及格":"不及格"}}</text> //条件表达式
通过开发者工具调试器的APPdata这个type,我们可以实时的调试每个页面的所有内部状态变量的取值
小程序的运行环境和基本架构
运行环境:每个小程序都是运行在它所在的微信客户端上的,通过微信客户端给它提供的运行环境,小程序可以直接获取微信客户端的原生体验和原生能力。
比如访问本机照片,视频,相机,地理位置。
基本架构:视图层和逻辑层
视图层:wxml和wxss,每个页面在Webview中进行渲染
逻辑层:js和配置json,JsCore中
两层运行在各自独立的进程中,about页和weekly页,都内置了一个vebviewId的内部状态变量,来记录他们各自是在几号webview进程中进行渲染的。
视图层和逻辑层基于数据绑定和事件机制进行通信,
基于数据绑定,在逻辑层对应的逻辑代码对相应的数据进行更新之后,逻辑层会将数据更新的部分传递给视图层,视图层会找的需要更新的部分进行更新。
基于事件机制,视图层会接受到用户的交互反馈的行为,将反馈的行为传递给逻辑层对应的时间处理函数进行处理。
条件渲染wx:if
类似于编程if语句,只有条件成立时,视图组件才会生成
条件渲染与使用hidden的区别
//使用wx:if,只有条件成立时,视图组件dom节点才生成
<text wx:if="{{thisWeekMovie.isHighlyRecommended}}">强烈推荐</text>
//使用hidden,视图组件dom节点一定会生成,hidden属性只是控制了其可见性而已
<text hidden="{{thisWeekMovie.isHighlyRecommended}}">强烈推荐</text>
hidden属性首次加载时开销较大
对于元素可见性不会频繁切换时,使用wx:if较好
列表渲染:重复生成组件wx:for
将weekly中全页面展示改为紧凑的块状展示结果,
假如requires请求从server端返回的是一个对象数组
data: {
weeklyMovieList:[
{
name:"教父",
comment:"点评:最精彩的剧本,最真实的黑帮电影",
imagePath:"/images/10.jpg",
isHighlyRecommended:true
},
{
name:"泰坦尼克号",
comment:"点评:失去的才是永恒的",
imagePath:"/images/11.jpg",
isHighlyRecommended:false
},
{
name:"这个杀手不太冷",
comment:"点评:小萝莉与怪蜀黍纯真灿烂的爱情故事",
imagePath:"/images/12.jpg",
isHighlyRecommended:true
}
],
},
数据列表渲染
//wxss
.movie{
display:flex;
}
.movie-details{
display:flex;
flex-direction:column;
width:550rpx;
}
.movie-image{
width:200rpx;
height:200rpx;
}
//wxml视图层提供循环的控制结构
<view class=''>
<view class="movie" wx:for="{{weeklyMovieList}}">
<image class="movie-image" src="{{item.imagePath}}"></image>
<view class="movie-details">
<text></text>
<text>第{{index+1}}周:{{item.name}}</text>
<text>"{{item.comment}}"</text>
<text style="color:red" wx:if="{{item.isHighlyRecommended}}">强烈推荐</text>
</view>
</view>
</view>
<view class="movie" wx:for="{{weeklyMovieList}}">
采用item为遍历变量
wx:for内置下标变量{{index}}
【问题】此时如果列表右边文字没有设置外层view的大小可能会挤压左边图片的大小,所以需要设置大小
swiper组件:幻灯片轮播展示
幻灯片轮播展示
swiper组件表示一个滑动容器,常用来表示幻灯片或者轮播图表示
每一个幻灯片使用子元素swiper-item表示
<swiper style="background:#f86;height:500px">//【易错】
<swiper-item>
<text>123</text>
<image src="/images/10.jpg"></image>
</swiper-item>
<swiper-item>
<text>456</text>
<image src="/images/11.jpg"></image>
</swiper-item>
<swiper-item>
<text>789</text>
<image src="/images/12.jpg"></image>
</swiper-item>
</swiper>
【问题】swiper元素默认高度为150px高,但是我们设置了image元素高度为240px;——我们需要设置swiper的高度,让每个元素都能显示出来
swiper的每个swiper-item元素,的宽度和高度和swiper的宽高时相同的,所以设置swiper的宽高时一般在swiper上统一设置。
列表展示换为幻灯片轮播方式展示
//wxss
.movie{
display:flex;
}
.movie-details{
display:flex;
flex-direction:column;
width:550rpx;
}
.movie-image{
width:200rpx;
height:200rpx;
}
.movie-swiper{
height:90vh;/*面板比例*/
}
//wxml
<swiper class="movie-swiper" indicator-dots="{{true}}">
<swiper-item class="movie" wx:for="{{weeklyMovieList}}">
<image class="movie-image" src="{{item.imagePath}}"></image>
<view class="movie-details">
<text></text>
<text>第{{index+1}}周:{{item.name}}</text>
<text>"{{item.comment}}"</text>
<text style="color:red" wx:if="{{item.isHighlyRecommended}}">强烈推荐</text>
</view>
</swiper-item>
</swiper>
indicator-dots="{{true}}"轮播图面板指示
需要放大展示
在每一个item内层加一个,采用全局样式布局。
全局mycontainer中,元素高度会超过swiper高度,需要对view高度做一个重新设置;
.movie-card{
height:100%;/*此时高度会恢复成父元素一样高*/
width:100%;
}
注意两层class样式的组合定义
幻灯片每一页前一页和后一页都露出一部分,便于用户触摸交互
设置swiper的属性
previous-margin="50rpx" next-margin="50rpx"
相邻的swiper-item是紧紧挨着放置的,内容也会紧紧挨着放置
为内容添加一定的边距,为里面的view元素设置外边距
样式优化
.movie{
display:flex;
}
.movie-details{
display:flex;
flex-direction:column;
width:550rpx;
}
.movie-image{
width:200rpx;
height:200rpx;
}
.movie-swiper{
height:90vh;/*面板比例*/
}
.movie-card{
height:100%;/*此时高度会恢复成父元素一样高*/
width:100%;
background-color: aqua;
margin:0,20rpx;
}
<!--pages/weekly/weekly.wxml-->
<view>
<swiper class="movie-swiper" style="height:1000rpx;background-color:red" indicator-dots="{{true}}" previous-margin="50rpx" next-margin="50rpx">
<swiper-item class="movie" wx:for="{{weeklyMovieList}}">
<view class="mycontainer movie-card">
<image class="movie-image" src="{{item.imagePath}}"></image>
<text>第{{index+1}}周:{{item.name}}</text>
<text>"{{item.comment}}"</text>
<text style="color:red" wx:if="{{item.isHighlyRecommended}}">强烈推荐</text>
</view>
</swiper-item>
</swiper>
</view>
四、生命周期函数onload()函数、this.setData、事件机制
swiper默认会切换到列表渲染的第一个幻灯片页
可以使用swiper组件的current属性来制定默认展示页面
默认current=‘0’,我们想设置为最后一个对象的序号
current="{{weeklyMovieList.length-1}}"
返回本周按钮,相对定位+绝对定位
.movie-card{
height:100%;/*此时高度会恢复成父元素一样高*/
width:100%;
background-color: rgb(241, 240, 240);
margin:0 20rpx;
padding:0 30rpx;/*易错,中间不用逗号隔开*/
position:relative;
}
.return-button{
position:absolute;
right:40rpx;
top:40px;
font-size:26rpx;
font-style:italic;
border: 1px solid blue;
border-radius: 10%;
}
<text class="return-button">返回本周</text>
父级元素采用相对定位,子级元素采用绝对定位
最后一张也生成了返回本周,条件渲染
<text wx:if='{{index<(weeklyMovieList.length-1)}}' class="return-button">返回本周</text>
绑定事件,返回本周
将current属性改为最后一个页面,
将current绑定到一个内部状态变量上
让其初始值为数组长度-1,在事件处理过程中,更新current,
问题:不能直接定义currentIndex=weeklyMovieList.length-1,
需要在onload函数中,页面初始化时setData
data:{
currentIndex:0
}
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
this.setData({
currentIndex:this.data.weeklyMovieList.length-1
})
},
【易错】在js中使用data数据时,需要使用this.data前缀
onload()
onShow()每一次页面从隐藏状态变为显式可见都要调用一次
onReady()页面已经初始化完成,可以进行页面交互时调用
onHide()每一次被隐藏
onUnload()页面被关闭,如redirect重定向
每一个页面加载,调用onLoad,onShow,onReady三个函数
逻辑层对数据进行更新必须采用this.setData方法调用
this.setData({})
小程序没有提供逻辑层API对视图直接更新,
只能通过视图层建立数据绑定,逻辑层js对视图层绑定的内部状态数据进行更新,从而间接通过框架对视图层进行更新
对内部状态变量直接赋值写入,不能使得视图一起更新,且很容易引起数据不一致的问题
要在小程序中更新内部状态变量,只能使用this.setData方法
告诉框架,对数据更新,并且对视图层进行更新
this.setData功能
更新已有的内部状态变量的值,
也可动态新增变量(可以不先定义currentIndex内部状态变量)
还可实现对一小部分的数据进行更新,如weeklyMovieList数组的最后一个元素电影的name进行更新,“对指定路径的属性尽心更新”
视图层的更新,不会引起内部状态变量的更新(切换weekly页面的swiper-item,其属性current是会变化,但currentIndex并不会发生变化)
小程序中视图层对内部状态变量的绑定是一个单向绑定
事件机制
事件绑定
button元素绑定了一个事件处理函数f0,
f0是在button元素所在的页面,所对应的页面对象中定义的;
当button元素被用户点击,会触发一个tap事件,
框架会将事件发生时的信息封装到一个事件对象中,然后将事件对象传递给绑定的时间处理函数f0进行处理
冒泡事件和非冒泡事件
冒泡事件:点击子元素,会触发子元素事件;子元素会将事件传递给父元素,如果父元素也定义了事件,也会触发;bindTap
非冒泡事件:不会将时间传递给父元素;catchTap
事件对象(事件触发时,从视图层传递给逻辑层的事件对象包含的信息)
点击”返回本周“
<text bindtap="f0" wx:if='{{index<(weeklyMovieList.length-1)}}' class="return-button">返回本周</text>
f0:function(){
this.setData({
currentIndex:this.data.weeklyMovieList.length-1
})
}
五、视图层组件的自定义属性+动态跳转id、逻辑层动态跳转后id的获取和视图渲染
视图层组件的自定义属性+动态跳转id(weekly页)
给每一个电影卡片定义绑定一个事件处理函数,跳转到对应的电影详情页中
页面跳转,但此时都是跳转到同一个detail页面中
<swiper-item class="movie" wx:for="{{weeklyMovieList}}">
<view bindtap="f1" class="mycontainer movie-card">
f1:function(event){
wx.navigateTo({
url: '/pages/detail/detail',
})
}
想要跳转到每一个电影对应的详情信息,对detail页做一个参数处理,如id
f1:function(event){
wx.navigateTo({
url: '/pages/detail/detail?id=77',
})
}
每一次点击一个电影卡片对应的id取值是不一样的,如何从视图层将id传递到事件处理函数中。
为每个电影新增一个id值,接下来每一个view元素被点击后将id传递给时间处理函数处理
通过事件对象信息event.currentTarget找到当前卡片的子元素,在小程序中不支持;
打印event.currentTarget,dataSet属性是元素自定义属性
为组件定义一个“data-”自定义测试属性,转换为事件对象中是一个“驼峰表示法”
当一个组件元素触发一个事件的时候,在其封装的事件对象中,记录了一些关键性的数据,这些关键性数据实际上是抽取的以“data-”这样形式声明的自定义用户数据。
在事件处理函数中,属性的提取
f1:function(event){
//【关键】
var movieId=event.currentTarget.dataset.movieId;
console.log(movieId);
wx.navigateTo({
url: '/pages/detail/detail?id='+movieId,
})
}
动态跳转后id获取和视图渲染(detail页)
“返回本周”采用catchtap绑定事件,是非冒泡事件;bindtap是冒泡事件
只希望当前元素做事件相应处理
希望detail页自身能够知道在对应的完整url中被指定的id参数是多少
页面初始化获取query参数:onLoad(option)
程序框架在每次以完成的url跳转打开detail页时,会首先调用这个detail页面注册的onLoad生命周期函数,来对detail进行初始化;
【关键】在调用onLoad方法时,会将url中问号后面的queystring中的每个参数值解析出来,组成一个javascript参数对象,然后将这个对象的实参值传递给onLoad方法
weekly.js
details.js/onLoad()
options对象
处理流程:
weekly页面第99号电影卡片被点击,会调用99号卡片所绑定的tap事件处理函数f1,
通过事件处理对象event获取到99号卡片元素“自定义的数据属性movieId的取值,
小程序框架再以附带id为99完整的URL来打开detail页;
首先会将url中包含的id=99的querystring解析成为一个options参数对象,
detail页面调用onLoad(options)生命周期函数,并且给onLoad生命周期函数传入options对象,
致辞detail页面中,能够获取到weekly页面中本次被打开电影卡片id,
后面可以将获取的电影id保存到detail页面状态数据中,然后再据其进行detail页面视图渲染
此时只是在detail页面中打印出id值
onLoad: function (options) {
this.setData({
movieId:options.id
})
},
<text>movieId={{movieId}}</text>
在detail页面上渲染更多的详情信息——发起request请求,获取数据,渲染视图
六、发起request请求+调用server端API,完成detail详情页面数据+视图渲染
发起请求requestAPI
request请求
wx.request({
//传递参数
url: 'url',
method:"GET",
data:{
id:1,
name:"liujie"
},
header:{
},
//回调函数,小程序接收到返回的response后的处理
//小程序在接受http返回的response之后,会对response进行解析,将其中关键数据抽取出来封装成为一个js对象,然后传递给js回调函数的res参数
success:function(res){
console.log(res);
},
//调用失败,例如网络超时
fail:function(){
},
//无论成功还是失败,都会调用
complete:function(){
}
})
合法域名检验
小程序对每一个网络请求指定的url对应的域名,都要求在小程序的后台中登记配置,每一个配置的域名必须是经过ICP备案的。
request方法调用,不同于jQuery的Ajax调用,在运行时接收到response之后,无论状态码是“200ok”还是对应错误的状态码(如403或404),都视为请求成功,然后进行下一步处理
success接收到的res回调函数包含信息
403返回
有一个data属性,抽取了response.body中的文本,然后转华为了一个String
header中返回的content-Type:“text/html”
如果返回header中content-Type为一个application json格式,返回的response的body中就是一个json文本,小程序运行环境就会对json文本作进一步处理,将其解析为一个对应js对象
response的三个属性
data属性,
header属性,
statusCode属性,返回状态码,如statusCode:403
request是一个异步调用,调用request方法之后,不会阻塞,会立马返回,自己返回之后就会执行后面对应的语句或逻辑;
只是小程序运行环境在后台监听什么时候能够收到response,然后调用对应的回调函数进行处理。
调用server的API,渲染detail详情页
调用serverAPI
var that = this
wx.request({
url: "http://101.200.78.125:8081/getMovie?id=" + options.id,
header: {
"content-type": "json"
},
//method默认为GET,data属性也不需要
success: function (res) {
console.log(res)
//判断response有效
if(res.statusCode==200){
//设置数据,用于渲染视图
that.setData({
movie: res.data
})
}
}
})
豆瓣API将小程序请求禁止了,每一个小程序请求有一个固定的referer header,且固定不可设置
收到返回的response之后,通过this.setData将数据保存到一个页面状态变量中
【错误】在success回调函数中进行处理的时候,此时的this指针指向success回调函数所在的==参数对象==(即wx.request函数的参数对象),不再指向页面注册的页面对象,此时的this就没有setData方法
对象的方法中this的指向,指向其所属的对象
解决办法:在调用wx.request之前,先对页面对象做一个保存
var that=this;
将接受到的电影详情数据,渲染到视图中展示
通过新增的内部状态变量movie,来对detail页面相关属性进行数据绑定;
//detail.wxml
<!--pages/detail/detail.wxml-->
<view class="mycontainer">
<image src="{{movie.images.small}}"></image>
<text style="font-weight:bold;font-size:50rpx">{{movie.title}}</text>
<text>想看:{{movie.wish_count}}</text>
<text>收藏:{{movie.collect_count}}</text>
<text>评分:{{movie.rating_average}}</text>
<text>简介:{{movie.summary}}</text>
</view>
根据statusCode判断返回的response是否时成功的还是失败的
if(res.statusCode==200){
七、动态设置顶部导航栏的标题、设置和隐藏页面加载时顶部导航栏的加载动画、常见页面事件处理函数+自定义页面转发
onLoad: function (options) {
//console.log(options.id)
this.setData({
mid: options.id
})
var that = this
wx.request({
url: "http://101.200.78.125:8081/getMovie?id=" + options.id,
header: {
"content-type": "json"
},
success: function (res) {
console.log(res)
//判断response有效
if(res.statusCode==200){
//设置数据
that.setData({
movie: res.data
})
//【3】动态设置顶部导航栏标题
wx.setNavigationBarTitle({
title: res.data.rating_average + "分: " + res.data.title,
})
//【2】响应到达后,隐藏顶部导航栏加载特效
wx.hideNavigationBarLoading()
}
}
})
//【1】响应到达前加载顶部导航栏加载特效
wx.showNavigationBarLoading()
},
//【4】自定义页面转发
onShareAppMessage: function () {
return {
title: "向你推荐:" + this.data.movie.title
}
}
设置和隐藏页面加载时顶部导航栏的加载动画
detail页面打开时,在开始很短时间内,页面相关数据显示的都是空白;
wx.request是异步的,请求发出以后,就立马返回了,此时页面的初始化就完成了;
就开始进入wxml视图的渲染,视图渲染的时候回去找内部状态变量movie,但此时request请求还未返回响应,此时的还没有内部状态变量movie;此时wxml将所有数据绑定的表达式渲染的结果都置为空白;
只有当经过很短的时间之后,当请求返回成功之后,才会进入回调函数,
通过setData设置内部状态变量movie,并且让小程序框架自动更新视图重新渲染数据,获取到的数据才会真正加载到视图。
可以在请求的响应还未返回时,在页面顶部导航栏设置一个页面加载动画,等响应返回以后数据加载完毕再动态将页面顶部导航栏loading动画隐藏
加载动画 wx.showNavigationBarLoading()
隐藏动画 wx.hideNavigationBarLoading()
根据返回的电影详情数据中的字段,动态设置页面顶部导航栏标题
//动态设置顶部导航栏标题
wx.setNavigationBarTitle({
title: res.data.rating_average+"分"+res.data.title,
})
常见页面事件处理函数+自定义页面转发
自定义页面转发
/**
* 用户点击右上角分享
*/
onShareAppMessage: function () {
return{
title:"向你推荐"+this.data.movie.title
}
}
八、server端JSON文件、站点定义
json文件
//douban.json
{
"id1291841":{
"title":"教父",
"wish_count":500,
"collect_count":1000,
"rating_average":9.7,
"summary":"做精彩的剧本,也是做真实的黑帮电影,从一个男生真正成为一个男人的电影",
"images":{
"large":"http://101.200.78.125:8081/public/images/1.jpg",
"middle":"http://101.200.78.125:8081/public/images/1.jpg",
"small":"http://101.200.78.125:8081/public/images/1.jpg"
}
},
"id1292722":{
"title":"这个杀手不太冷",
"wish_count":500,
"collect_count":1000,
"rating_average":9.7,
"summary":"做精彩的剧本,也是做真实的黑帮电影,从一个男生真正成为一个男人的电影",
"images":{
"large":"http://101.200.78.125:8081/public/images/1.jpg",
"middle":"http://101.200.78.125:8081/public/images/1.jpg",
"small":"http://101.200.78.125:8081/public/images/1.jpg"
}
},
"id1295644":{
"title":"心灵奇旅",
"wish_count":500,
"collect_count":1000,
"rating_average":9.7,
"summary":"做精彩的剧本,也是做真实的黑帮电影,从一个男生真正成为一个男人的电影",
"images":{
"large":"http://101.200.78.125:8081/public/images/1.jpg",
"middle":"http://101.200.78.125:8081/public/images/1.jpg",
"small":"http://101.200.78.125:8081/public/images/1.jpg"
}
}
}
nodejs服务器站点定义
//nodejs服务器
var express = require('express');
var app = express();
var fs = require("fs");
//获取静态资源
app.use('/public', express.static('public'));
//提供访问接口API
app.get('/getMovie', function (req, res) {
// 读取已存在的数据
fs.readFile( __dirname + "/" + "douban.json", 'utf8', function (err, data) {
data = JSON.parse( data );
console.log( data );
var key="id"+req.query.id;
var resdata = data[key]
console.log( resdata );
res.header("Content-Type", "application/json; charset=utf-8")//【易错】不可遗忘,定义格式;
res.end( JSON.stringify(resdata));
});
})
var server = app.listen(8081, function () {
var host = server.address().address
var port = server.address().port
console.log("应用实例,访问地址为 http://%s:%s", host, port)
})