第二讲 初识小程序
2.1 第一个实战项目:电影周周看V1
2.2 创建项目和目录文件结构
小程序包含一个描述整体的APP和多个描述各页面的page
一个小程序主体部分由三个文件组成,必须放在项目的根目录,如下:
默认工程文件:project.config.json
.json
后缀的JSON
配置文件.wxml
后缀的WXML
模板文件.wxss
后缀的WXSS
样式文件.js
后缀的JS
脚本逻辑文件
js
json
{
"pages":["pages/about/about" ]
}
wxml
wxss
pages/about
js
page({})
json
wxml
<text claass="info">hello word </text>
wxss
.info{
font-weight:bold;
font-size:30px;
}
2.3 页面配置初探
index.json:
{
"navigationBarTitleText": "首页",
"navigationBarBackgroundColor": "#fff",
"navigationBarTextStyle": "black"
}
2.4 VIEW、TEXT、IMAGE组件
class
id
style
bindtap="f0"//函数
hidden="true"//是否隐藏
data-user-name="user"//自定义属性
index.wxml
<view>
<image src="\pages\images\u0.jpg"></image>
<text>电影周周看</text>
<text>我每周推荐一部好片</text>
<text>我的微博:@星空风月</text>
</view>
2.5 快速实现基本布局
vr:viewport height
1、普通布局:
about.wxml
<view class="container">
<image src="/pages/images/u0.jpg"></image>
<text>电影周周看</text>
<text>我每周推荐一部好片</text>
<text>我的微博:weibo.com/@星空风月</text>
</view>
about.wxss
.container{
background-color: #eee;
height: 100vh;
text-align: center;
}
text{
display: block;/*显示为块级元素*/
}
image,text{
margin-bottom: 50px;
}
2、应用弹性盒子布局
优点:比较统一、方式灵活
.container{
background-color: #eee;
height: 100vh;
display: flex;/*变为flex container 元素从左往右*/
flex-direction: column;/*改为垂直从上往下*/
justify-content: space-around;/*在主轴方向上的聚集和分布方式*/
align-items: center;/*居中*/
}
2.6 让元素大小适配不同宽度屏幕
小程序规定所有设备的屏幕宽高为:750rpx
iPhone6屏幕:
px:rpx 比例为 1:2
/* 头像图片 */
.about_img{
width: 375rpx;
height: 375rpx;
border-radius: 50%;
}
/* 电影周周看 */
#about_zzk{
font-weight: bold;
font-size: 60rpx;
}
vh 说明:
相对于视口的高度。视口被均分为100单位的vh
示例代码:
h1 { font-size: 8vh; }
如果视口的高度是200mm,那么上述代码中h1元素的字号将为16mm,即(8x200)/100
2.7 新增“每周推荐”WEEKLY页并快速调试
每一个用户可能访问到的页面,都需要在前局配置中来登记他的访问路径。
weekly.js:调用page配置函数,来给页面注册一个空对象 Page({})
weekly.json:使用 { } 创建空的json对象配置文本
weekly.wxml:
<view class="container">
<text id="about_zzk">本周推荐</text>
<image class="about_img" src="/pages/images/handou.jpg"></image>
<text>憨豆先生</text>
<text>点评:最精彩的剧本是最真实的黑帮电影</text>
</view>
weekly.wxss:
.container{
background-color: #eee;
height: 100vh;
display: flex;/*变为flex container 元素从左往右*/
flex-direction: column;/*改为垂直从上往下*/
justify-content: space-around;/*在主轴方向上的聚集和分布方式*/
align-items: center;/*居中*/
}
2.8 使用NAVIGATOR组件-从ABOUT页跳转到WEEKLY页
display: black 块状元素
display: inline
open-type="redirect"不可返回
open-type="navigate" 默认可返回
open-type="redirect" 不可返回
about.wxml
<view class="container">
<image class="about_img" src="/pages/images/u0.jpg"></image>
<text id="about_zzk">电影周周看</text>
<view>
<text>我</text><navigator url="/pages/weekly/weekly" style=\'display:inline\' open-type="navigate" hover-class="nav-hover" class="nav-default">每周推荐</navigator><text>一部好片</text
>
</view>
<text>我的微博:weibo.com/@星空风月</text>
</view>
about.wxss
.container{
background-color: #eee;
height: 100vh;
display: flex;/*变为flex container 元素从左往右*/
flex-direction: column;/*改为垂直从上往下*/
justify-content: space-around;/*在主轴方向上的聚集和分布方式*/
align-items: center;/*居中*/
}
/* 头像图片 */
.about_img{
width: 375rpx;
height: 375rpx;
border-radius: 50%;
}
/* 电影周周看 */
#about_zzk{
font-weight: bold;
font-size: 60rpx;
}
/* 默认蓝色放在前 */
.nav-default{
color: blue;
}
/* 点击后的红色放在后面 */
.nav-hover{
color: red;
}
2.9 配置TABBAR-对若干一级页面的入口链接
<navigator>元素点击无效,设置
open-type=“switchTab”跳转并改变tabBar图标跳转
在app.json中使用tabBar属性
{
"pages": [
"pages/about/about",
"pages/weekly/weekly"
],
"tabBar": {
"list": [
{
"pagePath": "pages/weekly/weekly",
"text": "每周推荐",
"iconPath": "pages/images/icons/weekly.png",
"selectedIconPath": "pages/images/icons/weekly-selected.png"
},
{
"pagePath": "pages/about/about",
"text": "关于",
"iconPath": "pages/images/icons/about.png",
"selectedIconPath": "pages/images/icons/about-selected.png"
}
],
"color": "#000000",
"selectedColor": "#00f"
}
}
"color": "#000000",
"selectedColor": "#00f"
2.10 配置全局的导航栏样式
顶部导航栏样式默认使用黑底白字
代码直接复制的方法必然会带来代码升级时候的问题
在app.json中使用Windows属性
"window": {
"navigationBarBackgroundColor": "#ffffff",
"navigationBarTextStyle": "black",
"navigationBarTitleText": "电影周周看",
"backgroundColor": "#eeeeee",
"backgroundTextStyle": "light",
"enablePullDownRefresh": false
}
第三讲 电影周周看v2
3.1 数据绑定
一般方法通过ajax调用server的数据
weekly.js 里面添加数据变量:
Page({
data: {
thisWeekMoview: [
{
name: "教父",
comment: "最精彩的剧本,最真实的黑帮电影。",
imagePath: "/images/jf.jpg"
}
],
count: 123
}
})
weekly.wxml页面
<view class="container">
<text id="about_zzk">本周推荐</text>
<image class="about_img" src="{{thisWeekMovie.imagePath}}"></image>
<text>{{thisWeekMovie.name}}</text>
<text>点评:{{thisWeekMovie.comment}}</text>
</view>
3.2 小程序运行环境与基本架构 VIDEO
在小程序调试窗口里面的 AppData,可以对页面里的数据进行调试。我们可以看到,小程序给页面 weekly 添加了一个变量 webviewId 等于10。这个是做什么用的呢?
这就需要了解小程序的运行环境和运行架构。
运行环境: 每个小程序都是运行在它所在的微信客户端上的,通过微信客户端给它提供运行环境,小程序可以直接获取微信客户端的原生体验和原生能力。
视力层和逻辑层: 小程序的运行环境分成渲染层和逻辑层,其中 WXML 模板和 WXSS 样式工作在渲染层,JS 脚本工作在逻辑层。小程序的渲染层和逻辑层分别由2个线程管理:渲染层的界面使用了WebView 进行渲染;逻辑层采用JsCore线程运行JS脚本。一个小程序存在多个界面,所以渲染层存在多个WebView线程,这两个线程的通信会经由微信客户端做中转,逻辑层发送网络请求也经由Native转发,小程序的通信模型下图所示。
所以,刚才我们在 AppData 中可以看到,about页和weekly页都内置了一个 webviewId 的内部状态变量,记录它们各自是在几号 webview 进程中进行渲染的。
3.3 条件渲染
条件渲染指的是:条件成立时才渲染生成。
拿上面的例子来看,我们给推荐页面的电影添加一个这段,表明这个电影是不是强烈推荐的。
isHighlyRecommended: true
我们现在要做的一个改动就是,希望在视图中,对于真正想强烈推荐的电影,我们要显示一个强烈推荐的红色标记。
首先我们把强烈推荐的元素定义出来,添加到 weekly.wxml 中:
<text style="font-size:16px; color:red;"> 强烈推荐 </text>
这时可以看到,在视图中,出现了红色的 “强烈推荐” 的字样。
但是这个是肯定会生成的,但我们需要的效果是,如果电影是要推荐的,就生成;不是推荐的,就不生成。
所以,我们就可能 通过 wx:if 做条件判断来实现。代码可以修改为:
<text wx:if="{{thisWeekMovie.isHighlyRecommended}}" style="font-size:16px; color:red;">强烈推荐</text>
这个意思是,强烈推荐这个 text 元素,渲梁生成的条件是:绑定到了 thisWeekMoview 的 isHighlyRecommended 属性上。当这个属性是 true 的情况下,这个 text 元素会被生成,如果这个属性是 false 的情况下,这个 text 元素就不会生成。
同时,我们也可以使用 hidden 属性来实现这个效果。 代码如下:
<text hidden="{{!thisWeekMovie.isHighlyRecommended}}" style="font-size:16px; color:red;">强烈推荐</text>
这里注意是求反的操作。当用户没有推荐的时候,hidden是true;用户强烈推荐的时候,hidden是false,所以是求反的操作。
此时,我们在 AppData 里面进行查看,可以看到,这个 text 元素无论 hidden 是取 true 还是 false,都始终是生成的。因此,我们可以知道,使用 hidden 属性时,这个元素总是要被渲染生成的,hidden 只是控制了其可见性而已。
那么,在实际应用中,我们该如何选择呢?
从上面的例子我们可以看到,当wx:if的条件值切换时,框架有一个局部渲染的过程,他会确保条件在切换是销毁或者重新渲染。同时wx:if也是有惰性的,如果初始渲染条件为false,框架什么也不会做,只有在条件第一次变为真的时候才会开始渲染。因此,对于可见性需要频繁切换的时候,不建议使用条件渲染,因为它的开销会比较大,这个时候就使用 hidden
对于我们的这个例子,我们要如何选择呢? 当电影列表从服务器获得以后,用户就不会对是否推荐的信息进行修改。意思就是,强烈推荐这个元素的渲染条件,用户是不会去发生切换的。所以这个时候,我们应该使用 条件渲染来做 这件事情。这个时候如果使用 hidden,他的初始化开销会增大。博主没有去推荐这个电影,它也会在初始生成的时候,去生成这么一个元素。
3.4 列表渲染
原来的weekly.wxss
.container{
background-color: #eee;
height: 100vh;
display: flex;/*变为flex container 元素从左往右*/
flex-direction: column;/*改为垂直从上往下*/
justify-content: space-around;/*在主轴方向上的聚集和分布方式*/
align-items: center;/*居中*/
}
原来的weekly.wxml
<view class="container">
<text id="about_zzk">本周推荐</text>
<image class="about_img" src="{{thisWeekMovie.imagePath}}"></image>
<text>{{thisWeekMovie.name}}</text>
<text>点评:{{thisWeekMovie.comment}}</text>
<text hidden="{{!thisWeekMovie.isHighlyRecommended}}" style="font-size:32rpx;color:red;">※ 强烈推荐</text>
</view>
现在的:
weekly.wxss
.movie{
display: flex;
}
.movie-details{
display: flex;
flex-direction: column;
width: 550rpx;
}
.movie-image{
width: 200rpx;
height: 200rpx;
}
weekly.wxml
<view>
<view class="movie" wx:for="{{WeeklyMovieList}}">
<image class="movie-image" src="{{item.imagePath}}"></image>
<view class="movie-details">
<text>第{{index+1}}周:{{item.name}}</text>
<text>点评:{{item.comment}}</text>
<text hidden="{{!item.isHighlyRecommended}}" style="font-size:32rpx;color:red;">※ 强烈推荐</text>
</view>
</view>
</view>
weekly.js
Page({
data: {
WeeklyMovieList:[
{
name: "泰坦尼克号",
comment: "失去的才是永恒的",
imagePath: "/images/titanic.jpg",
isHighlyRecommended: false,
},
{
name: "这个杀手不太冷",
comment: "小萝莉与怪蜀黍纯真灿烂的爱情故事",
imagePath: "/images/leon.jpg",
isHighlyRecommended: false,
},
{
name: "教父",
comment: "最精彩的剧本,最真实的黑帮电影。",
imagePath: "/images/jf.jpg",
isHighlyRecommended: true,
}
]
}
})
3.5 使用SWIPER组件
weiper元素默认:150像素高,image元素默认:240元素高
sweiper元素设置的宽高weiper-item百分百比例显示
indicator-dots="ture" 属性显示面板指示
3.6 页面的生命周期函数
需求1:
对于 swiper ,要设置默认显示的那页幻灯片,可以添加一个 current 属性,这个属性默认值是0。也就是说,首张幻灯片页是默认显示的。现在要做的是,因为用户每次最想看到的是,本周推荐的页。所以,要把 swiper 默认设置成最后一页幻灯片。
最后一页的序号是 数组长度减1。解决方案是,把 current 属性这样绑定:
current = \'{{weeklyMovieList.length-1}}\'
需求2:
- 进而会引出 onLoad 生命周期函数,可以查看如何对元素进行初始化;
- 介绍 onShow, onReady, onHide, onUnload 生命周期函数。
bindtap绑定事件处理函数f0
<text bindtap=\'f0\' wx:if=\'{{index < (weeklyMovieList.length - 1)}}\' class=\'return-button\'>返回本周</text>
<text bindtap=\'f0\' wx:if=\'{{index < (weeklyMovieList.length - 1)}}\' class=\'return-button\'>返回本周</text>
onLoad: function (options) {
this.setData({
currentIndex: this.data.weeklyMovieList.length - 1
})
},
onload,事件会在页面或图像加载完成后立即发生。
onShow, 当页面每一次显示,都要调一次,每一次页面从隐藏到可见,都会调用
onReady, 等页面渲染完成,全部好了,已经可以交互的时候被调用一次
onHide, 当页面每次隐藏的时候调用一次
onUnload,当页面被关闭或卸载的时候调用
position:relative;相对定位
position:absolute;相对定位
3.7 更新数据
在这里,展示了一种数据更新的方式,就是直接像下面函数的形式来进行更新:
f0: function(event){
this.data.count = this.data.count + 1
}
反复点击按钮,会发现页面显示并没有更新。但是进入 AppData 查看,可以发现 count 的值已经更新到了 9。
所以,这种通过对变量直接赋值写入的方式,不能让框架自动更新,而且,非常容易引起数据不一致问题。所以,对小程序中的变量进行更新,不能采取直接赋值的方式,而必须采用小程序提供的 this.setData 方法。
发现实际的写法为:
f0: function (event) {
this.setData({
currentIndex: this.data.weeklyMovieList.length - 1
})
}
3.8 事件机制
前面的应用里,我们已经使用了事件函数。这一节我们要讲解如下事项:
- 事件绑定
- 冒泡事件与非冒泡事项
- bind 绑定 VS catch 绑定
- 事件对象简介
- 对于点击的操作有两种处理方式:
<button catchtap=\'f0\'> +1 </button>
<button bindtap=\'f0\'> +1 </button>
这两种有什么区别呢?首先我们要了解冒泡事件和非冒泡事件。小程序中事件分为冒泡事件和非冒泡事件:
- 冒泡事件:当一个组件上的事件被触发后,该事件会向父节点传递。
- 非冒泡事件:当一个组件上的事件被触发后,该事件不会向父节点传递。
- 在小程序事件系统文档中,给出了哪些是冒泡事件。
对于 bindtap ,如果事件触发了,就会向上传递给父元素。也就是说,button 如果点击了,就会传递给外边的 view 元素,如果 view 元素里面自己也有一个 bindtap 函数,它也会调用这个函数进行处理。
相反,如果这里使用 catchtap ,那么点击以后,就会阻止元素向上传递。也就是说,按钮点击以后,只会处理自己的函数,但外层的 view 元素,就不会进行相应处理。
接着,我们看看事件对象包含哪些信息。我们把f0函数修改如下:
f0: function(event){
console.log(event)
}
点击以后,可以在 log 里看到如下事件触发后,方方面面的信息,具体如下:
比如说事件的类型,是一个 tap 事件,还有一个是 currentTarget ,指向的是当前事件处理的元素。可以观察到,currentTarget 还有一个 dataset 属性,这个还会在后边讲到。
第四讲 电影周周看v3
4.1 组件的自定义数据属性
继续完善电影周周看微信小程序,
- 需求:从weekly 页面上的电影卡片跳转到电影详情页,因此,要新增 detail页面
- 使用 wx.navigateTo()
- 参数化的 page path
- 组件的自定义数据属性:向逻辑层的业务数据传递
首先,新建details页面,这里给出 detail页的基本代码:
details.wxml
<text>detail page</text>
detail.json
{
"navigationBarTitleText": "电影详情页"
}
detail.js
Page({})
然后,在weekly.wxml中,每一个电影,都对应了一个卡片,我们找到它所在的view,需要给它一个点击函数,然后我们在weekly.wxml新增代码:
这样就绑定了tab事件处理函数,同进,在weekly.js里面添加事件处理函数:
从代码中可以看到,在f1中,实现了页面的跳转,使用的是wx.navgigateTo 函数。这个函数的功能是保留当前页面,中转到应用内的某个页面,同时,使用 wx.navigateBack 函数可以返回原页面。
同时,微信还提供了其它几个方式,比如,wx.redirectTo 是关闭当前页面,跳转到应用中的某个页面(注意:使用的过程中,当前的页面是会关闭的)。类似的还有 wx.switchTab ,是跳转到 tabBar 页面,并关闭当前所有非 tabBar 页面。
现在可以看一下效果,当点击一个电影元素,就跳转一下面的 detail 页:
同时,可以注意到,每次点击一个电影卡片,我们希望得到的详情是不一样的。那么如何实现这一功能呢?这样,我们给每一个电影的信息里,添加一个元素 id,如下所示:
每个电影的 id 是不一样的,同进,在视图层 weekly.wxml 中添加代码,把电影的 id 显示出来,如下图所示:
那么问题来了,如何把 view 元素中的取值,传递给逻辑层呢?
为详细说明这一操作,我们给 weekly.wxml 添加下面代码:
然后,在逻辑层 weekly.js 添加下面的代码:
接着,运行小程序,点击电影卡片,可以看到控制台有下面的输出:
1291841
blabla
这说明什么呢?当视图层的 view 触发一个事件的时候,它封装了一些数据,这些关键数据,实际上是抽取的,形式为 " data-" 开头,声明的自定义的一些用户数据。
比如说,data-user-name,到逻辑层就变为了:event.currentTarget.dataset.userName的格式
data-movie-id,到逻辑层就变成了:event.currentTarget.dataset.movieId 的格式。
这样,就要可以方便的把电影的 id 传递给 navigateTo 函数,如下所示:
4.2 电影详情页的基本框架
4.3 发起请求API
请发表评论