微信小程序项目实战
1. 前言叙述
1. 小程序没有DOM对象,一切基于组件化
2. 小程序的四个重要的文件
- *.js
- *.wxml —> view结构 ----> html
- *.wxss —> view样式 -----> css
- *. json ----> view 数据 -----> json文件
3. 小程序设置
- 小程序出于安全考虑所有的协议都是https协议,且如果没有在开发设置中配置请求的连接是无法访问指定的链接的。
- 一个微信小程序的并发网络请求数量被限制在最多5个
4. 储备知识
- 理解事件机制
- 理解组件化
- 理解数据绑定
- Flex布局
- 移动端适配方案
2. Flex布局简介
1. 什么是flex布局?
- Flex是Flexible Box的缩写,意为”弹性布局”,用来为盒状模型提供最大的灵活性。
- 任何一个容器都可以指定为Flex布局。
display: ‘flex’
2. flex属性
- flex-direction:
- row(默认值):主轴为水平方向,起点在左端。
- row-reverse:主轴为水平方向,起点在右端。
- column:主轴为垂直方向,起点在上沿。
- column-reverse:主轴为垂直方向,起点在下沿。
3. 学习地址:
http://www.runoob.com/w3cnote/flex-grammar.html
3. 移动端适配
1. 物理像素
- 屏幕的分辨率
- 设备能控制显示的最小单元,可以把物理像素看成是对应的像素点
2. 设备独立像素 & css像素
设备独立像素(也叫密度无关像素),可以认为是计算机坐标系统中的一个点,这个点代表一个可以由程序使用并控制的虚拟像素(比如:CSS 像素,只是在android机中CSS 像素就不叫”CSS 像素”了而是叫”设备独立像素”),然后由相关系统转换为物理像素。
3. dpr比 & DPI & PPI
- dpr: 设备像素比,物理像素/设备独立像素 = dpr, 一般以Iphon6的dpr为准 dpr = 2
- PPI: 一英寸显示屏上的像素点个数
- DPI:最早指的是打印机在单位面积上打印的墨点数,墨点越多越清晰
4. 小程序适配方案
Iphon6: 1rpx = 1物理像素 = 0.5px
微信官方提供的换算方式:
- 以iPhone6的物理像素个数为标准: 750;
- 1rpx = 目标设备宽度 / 750 * px;
- 注意此时底层已经做了viewport适配的处理,即实现了理想视口
5. 扩展内容
- 视网膜屏幕是分辨率超过人眼识别极限的高分辨率屏幕,由苹果公司在2010年iPhone4发布会上首次推出营销术语。
- iphone的dpr = 2; 人类肉眼分辨的极限
6. 小程序实战
1. 登陆版块
1. 获取登陆用户的信息数据
- wx.getUserInfo(OBJECT)
参数
属性 | 类型 | 说明 |
---|---|---|
withCredentials | boolean | 是否带上登录态信息。当 withCredentials 为 true 时,要求此前有调用过 wx.login 且登录态尚未过期,此时返回的数据会包含 encryptedData, iv 等敏感信息;当 withCredentials 为 false 时,不要求有登录态,返回的数据不包含 encryptedData, iv 等敏感信息。 |
lang | string | 显示用户信息的语言 |
success | function | 接口调用成功的回调函数 |
fail | function | 接口调用失败的回调函数 |
complete | function | 接口调用结束的回调函数(调用成功、失败都会执行) |
代码
onLoad: function(options){
// 获取用户登陆的信息
wx.getUserInfo({
success: (data) => {
console.log(data);
},
fail: () => {
console.log('获取用户数据失败')
}
})
}
data中的数据
2. 更新数据
- this.setData
- (this 为当前页面的实例对象)
- 结合ES6语法(箭头函数)获取正确的 this
代码
// 获取用户登陆的信息
wx.getUserInfo({
success: (data) => {
console.log(data);
// 更新data中的userInfo
this.setData({
userInfo: data.userInfo
})
},
fail: () => {
console.log('获取用户数据失败')
}
})
3. 将数据呈现在页面上
代码
<view class="container">
<image src="{{userInfo.avatarUrl}}"></image>
<text class="username">hello {{userInfo.nickName}}</text>
<view bindtap="handleParent" class="goStudy">
<text>开启小程序之旅</text>
</view>
</view>
效果
4. 用户授权
- open-type
参数
值 | 说明 |
---|---|
contact | 打开客服会话,如果用户在会话中点击消息卡片后返回小程序,可以从 bindcontact 回调中获得具体信息 |
share | 触发用户转发 |
getPhoneNumber | 获取用户手机号,可以从bindgetphonenumber回调中获取到用户信息 |
getUserInfo | 获取用户信息,可以从bindgetuserinfo回调中获取到用户信息 |
launchApp | 打开APP,可以通过app-parameter属性设定向APP传的参数 |
openSetting | 打开授权设置页 |
feedback | 打开“意见反馈”页面,用户可提交反馈内容并上传日志,开发者可登录小程序管理后台后进入左侧菜单“客服反馈”页面获取到反馈内容 |
代码
<view class="container">
<image src="{{userInfo.avatarUrl}}"></image>
<button open-type="getUserInfo">获取用户信息</button>
<text class="username">hello {{userInfo.nickName}}</text>
<view bindtap="handleParent" class="goStudy">
<text>开启小程序之旅</text>
</view>
</view>
效果
5. 判断用户是否授权
- wx.getSetting
- 获取用户的当前设置。返回值中只会出现小程序已经向用户请求过的权限。
参数
属性 | 说明 |
---|---|
success | 接口调用成功的回调函数 |
fail | 接口调用失败的回调函数 |
complete | 接口调用结束的回调函数(调用成功、失败都会执行) |
- success 回调函数
参数
属性 | 说明 |
---|---|
authSetting | 用户授权结果 |
代码
button不是固定存在
<button style="display: {{isShow?'block':'none'}}" open-type="getUserInfo">
获取用户信息
</button>
/**
* 页面的初始数据
*/
data: {
userInfo: {},
isShow: false
},
onLoad: function(options){
// 判断用户是否授权
wx.getSetting({
success: (data) => {
// console.log(data);
if (data.authSetting['scope.userInfo']) {//scope.userInfo为不规则属性,是一个整体,用数组表示,里面是一个字符串
// 用户已经授权,可以直接调用 getUserInfo 获取头像昵称
// console.log('已经授权');
// 更新用户数据
this.setData({
isShow: false
})
} else {
// 没有授权
// console.log('没有授权');
// 更新用户数据
this.setData({
isShow: true
});
}
}
});
}
6. 如何知道用户是否点击允许
- bindgetuserinfo
- 获取用户信息,可以从bindgetuserinfo回调中获取到用户信息
- 观察允许和拒绝情况数据的差别
用户允许
用户拒绝
代码
<button bindgetuserinfo="handleGetUserInfo"
style="display: {{isShow?'block':'none'}}"
open-type="getUserInfo">
获取用户信息
</button>
// 判断用户点击按钮的回调函数
handleGetUserInfo(data){
console.log('用户点击了',data);
// 判断用户是否点击了允许
if(data.detail.rawData){
// 用户点击了允许
this.getUserInfo();
}
}
2. 主页板块
1. 由登陆页面跳转到主页面
- wx.switchTab
- 跳转到 tabBar 页面,并关闭其他所有非 tabBar 页面
参数
属性 | 类型 | 说明 |
---|---|---|
url | string | 需要跳转的 tabBar 页面的路径(需在 app.json 的 tabBar 字段定义的页面),路径后不能带参数。 |
success | function | 接口调用成功的回调函数 |
fail | function | 接口调用失败的回调函数 |
complete | function | 接口调用结束的回调函数(调用成功、失败都会执行) |
代码
<view bindtap="handleParent" class="goStudy">
<text>开启小程序之旅</text>
</view>
handleParent(){
console.log('父元素');
// 跳转页面
wx.switchTab({
url: '/pages/list/list',
})
},
2. 轮播图组件
- swiper
- 滑块视图容器。其中只可放置swiper-item组件,否则会导致未定义的行为。
参数
属性 | 类型 | 默认值 | 说明 |
---|---|---|---|
indicator-dots | boolean | false | 是否显示面板指示点 |
indicator-color | color | rgba(0, 0, 0, .3) | 指示点颜色 |
indicator-active-color | color | #000000 | 当前选中的指示点颜色 |
autoplay | boolean | false | 是否自动切换 |
current | number | 0 | 当前所在滑块的 index |
interval | number | 5000 | 自动切换时间间隔 |
duration | number | 500 | 滑动动画时长 |
circular | boolean | false | 是否采用衔接滑动 |
vertical | boolean | false | 滑动方向是否为纵向 |
previous-margin | string | “0px” | 前边距,可用于露出前一项的一小部分,接受 px 和 rpx 值 |
next-margin | string | “0px” | 后边距,可用于露出后一项的一小部分,接受 px 和 rpx 值 |
display-multiple-items | number | 1 | 同时显示的滑块数量 |
skip-hidden-item-layout | boolean | false | 是否跳过未显示的滑块布局,设为 true 可优化复杂情况下的滑动性能,但会丢失隐藏状态滑块的布局信息 |
easing-function | string | “default” | 指定 swiper 切换缓动动画类型 |
bindchange | eventhandle | current 改变时会触发 change 事件,event.detail = {current, source} | |
bindtransition | eventhandle | swiper-item 的位置发生改变时会触发 transition 事件,event.detail = {dx: dx, dy: dy} | |
bindanimationfinish | eventhandle | 动画结束时会触发 animationfinish 事件,event.detail 同上 |
代码
<!-- 轮播图 -->
<swiper catchtap="carouselToDetail" indicator-dots="true"
indicator-color="green" indicator-active-color="deeppink"
autoplay="true" interval="5000" duration="500" circular="true">
<swiper-item>
<image src="/images/detail/carousel/01.jpg"></image>
</swiper-item>
<swiper-item>
<image src="/images/detail/carousel/02.jpg"></image>
</swiper-item>
<swiper-item>
<image src="/images/detail/carousel/03.jpg"></image>
</swiper-item>
<swiper-item>
<image src="/images/detail/carousel/04.jpg"></image>
</swiper-item>
</swiper>
3. 模版组件
- template
- WXML提供模板(template),可以在模板中定义代码片段,然后在不同的地方调用。
定义模版
- 使用 name 属性,作为模板的名字来标识模版。然后在
<template/>
内定义代码片段
代码
<template name="listTmp">
<view class="tmpContainer">
<view class="avatar_date">
<image src="{{avatar}}"></image>
<text>{{date}}</text>
</view>
<text class="company">{{title}}</text>
<image class="content_img" src="{{detail_img}}"></image>
<text class="content">{{detail_content}}</text>
<view class="love_attention">
<image src="/images/icon/star.png"></image>
<text>{{love_count}}</text>
<image src="/images/icon/view.png"></image>
<text>{{attention_count}}</text>
</view>
</view>
</template>
引用模版与模版样式
<!-- 引用模版 -->
<import src="/pages/template/template" />
/* 引入模版样式 */
@import "/pages/template/template.wxss";
使用模版
- 使用 is 属性,声明需要的使用的模板,然后将模板所需要的 data 传入
<!-- 运用模版 -->
<template is="listTmp" data='{{...item}}' />
模板的作用域
- 模板拥有自己的作用域,只能使用 data 传入的数据以及模板定义文件中定义的
<wxs />
模块。
4. 列表渲染
1. 引入外部数据
let datas = require('../../datas/list-data.js');// 注意这边要用相对路径
console.log(datas,typeof datas);
2. wx:for
- 在组件上使用 wx:for 控制属性绑定一个数组,即可使用数组中各项的数据重复渲染该组件。
- 默认数组的当前项的下标变量名默认为 index,数组当前项的变量名默认为 item
- 使用 wx:for-item 可以指定数组当前元素的变量名
- 使用 wx:for-index 可以指定数组当前下标的变量名
3. block wx:for
- 类似 block wx:if,也可以将 wx:for 用在
<block/>
标签上,以渲染一个包含多节点的结构块。
代码
<block wx:for="{{listArr}}" wx:key="{{index}}">
<view>
<template is="listTmp" data='{{...item}}' />
</view>
</block>
4. wx:key
-
如果列表中项目的位置会动态改变或者有新的项目添加到列表中,并且希望列表中的项目保持自己的特征和状态(如 input 中的输入内容,switch 的选中状态),需要使用 wx:key 来指定列表中项目的唯一的标识符。
-
wx:key 的值以两种形式提供
- 字符串,代表在 for 循环的 array 中 item 的某个 property,该 property 的值需要是列表中唯一的字符串或数字,且不能动态改变。
- 保留关键字 *this 代表在 for 循环中的 item 本身,这种表示需要 item 本身是一个唯一的字符串或者数字
- 如:当数据改变触发渲染层重新渲染的时候,会校正带有 key 的组件,框架会确保他们被重新排序,而不是重新创建,以确保使组件保持自身的状态,并且提高列表渲染时的效率。
-
如不提供 wx:key,会报一个 warning, 如果明确知道该列表是静态,或者不必关注其顺序,可以选择忽略。
3. 详情页板块
1. 事件系统
什么是事件
- 事件是视图层到逻辑层的通讯方式。
- 事件可以将用户的行为反馈到逻辑层进行处理。
- 事件可以绑定在组件上,当达到触发事件,就会执行逻辑层中对应的事件处理函数。
- 事件对象可以携带额外信息,如 id, dataset, touches。
事件的使用方式
- 在组件中绑定一个事件处理函数。
- 如bindtap,当用户点击该组件的时候会在该页面对应的Page中找到相应的事件处理函数。
- 在相应的Page定义中写上相应的事件处理函数,参数是event。
事件分类
-
事件分为冒泡事件和非冒泡事件:
- 冒泡事件:当一个组件上的事件被触发后,该事件会向父节点传递。
- 非冒泡事件:当一个组件上的事件被触发后,该事件不会向父节点传递。
-
WXML的冒泡事件列表:
类型 | 触发条件 |
---|---|
touchstart | 手指触摸动作开始 |
touchmove | 手指触摸后移动 |
touchcancel | 手指触摸动作被打断,如来电提醒,弹窗 |
touchend | 手指触摸动作结束 |
tap | 手指触摸后马上离开 |
longpress | 手指触摸后,超过350ms再离开,如果指定了事件回调函数并触发了这个事件,tap事件将不被触发 |
longtap | 手指触摸后,超过350ms再离开(推荐使用longpress事件代替) |
transitionend | 会在 WXSS transition 或 wx.createAnimation 动画结束后触发 |
animationstart | 会在一个 WXSS animation 动画开始时触发 |
animationiteration | 会在一个 WXSS animation 一次迭代结束时触发 |
animationend | 会在一个 WXSS animation 动画完成时触发 |
touchforcechange | 在支持 3D Touch 的 iPhone 设备,重按时会触发 |
- 注:除上表之外的其他组件自定义事件如无特殊声明都是非冒泡事件,如 form 的submit事件,input 的input事件,scroll-view 的scroll事件
事件绑定和冒泡
- 事件绑定的写法同组件的属性,以 key、value 的形式。
- key 以bind或catch开头,然后跟上事件的类型,如bindtap、catchtouchstart。在非原生组件中,bind和catch后可以紧跟一个冒号,其含义不变,如bind:tap、catch:touchstart。
- value 是一个字符串,需要在对应的 Page 中定义同名的函数。不然当触发事件的时候会报错。原生组件也支持bind后紧跟冒号的写法。
- bind事件绑定不会阻止冒泡事件向上冒泡,catch事件绑定可以阻止冒泡事件向上冒泡。
2. 数据动态展示
- 1. 引入外部数据
let datas = require('../../datas/list-data.js');
- 2. data-X 传递数据
- 在相应的Page定义中写上相应的事件处理函数,参数是event。
- list 页面
<!-- 运用模版 -->
<block wx:for="{{listArr}}" wx:key="{{index}}">
<view catchtap="toDetail" data-index="{{index}}">
<template is="listTmp" data='{{...item}}' />
</view>
</block>
// 点击跳转到detail详情页面
toDetail(event){
console.log(event);
// 获取点击跳转对应的下标
let index = event.currentTarget.dataset.index;
// 跳转到对应下标的详情页面
wx.navigateTo({
url: '/pages/detail/detail?index=' + index,
})
},
- detail 页面
data: {
detailObj: {},
index: null
},
onLoad: function (options) {
console.log(options);
// 获取参数值
let index = options.index;
// 更新data中detailObj的状态值
this.setData({
detailObj:datas.list_data[index],
index
});
4. 轮播图点击展示效果
1. 事件委托
事件委托给父元素:swiper
<swiper catchtap="carouselToDetail" indicator-dots="true" indicator-color="green" indicator-active-color="deeppink" autoplay="true" interval="5000" duration="500" circular="true">
<swiper-item>
<image data-index="1" src="/images/detail/carousel/01.jpg"></image>
</swiper-item>
<swiper-item>
<image data-index="0" src="/images/detail/carousel/02.jpg"></image>
</swiper-item>
<swiper-item>
<image data-index="2" src="/images/detail/carousel/03.jpg"></image>
</swiper-item>
<swiper-item>
<image data-index="3" src="/images/detail/carousel/04.jpg"></image>
</swiper-item>
</swiper>
2. 传递事件数据
// 轮播图跳转到对应下标的详情页面
carouselToDetail(event){
console.log(event);
let index = event.target.dataset.index;
wx.navigateTo({
url: '/pages/detail/detail?index=' + index,
})
}
3. currentTarget & target
区别:
- target指向的是触发事件的元素
- currentTarget指向的是捕获事件的元素
5. 收藏功能效果
1. 条件渲染(收藏图标动态显示)
- wx:if
- 在框架中,使用 wx:if="" 来判断是否需要渲染该代码块
- 也可以用 wx:elif 和 wx:else 来添加一个 else 块
<image catchtap="handleCollection" wx:if="{{!isCollected}}" src="/images/icon/collection-anti.png"></image>
<image catchtap="handleCollection" wx:if="{{isCollected}}" src="/images/icon/collection.png"></image>
/**
* 页面的初始数据
*/
data: {
isCollected: false,
isMusicPlay: false
}
- wx:if & hidden
- 因为 wx:if 之中的模板也可能包含数据绑定,所以当 wx:if 的条件值切换时,框架有一个局部渲染的过程,因为它会确保条件块在切换时销毁或重新渲染。
- 同时 wx:if 也是惰性的,如果在初始渲染条件为 false,框架什么也不做,在条件第一次变成真的时候才开始局部渲染。
- 相比之下,hidden 就简单的多,组件始终会被渲染,只是简单的控制显示与隐藏。
- 一般来说,wx:if 有更高的切换消耗而 hidden 有更高的初始渲染消耗。因此,如果需要频繁切换的情景下,用 hidden 更好,如果在运行时条件不大可能改变则 wx:if 较好。
2. 动态修改图标是否显示
// 收藏功能
handleCollection(){
let isCollected = !this.data.isCollected;
// 更新状态
this.setData({
isCollected
});
}
3. 交互反馈
- wx.showToast
- 显示消息提示框
属性 | 类型 | 说明 |
---|---|---|
title | string | 提示的内容 |
icon | string | 图标 |
image | string | 自定义图标的本地路径,image 的优先级高于 icon 1.1.0 |
duration | number | 提示的延迟时间 |
mask | boolean | 是否显示透明蒙层,防止触摸穿透 |
success | function | 接口调用成功的回调函数 |
fail | function | 接口调用失败的回调函数 |
complete | function | 接口调用结束的回调函数(调用成功、失败都会执行) |
- 注意
- wx.showLoading 和 wx.showToast 同时只能显示一个
- wx.showToast 应与 wx.hideToast 配对使用
//提示用户
let title = isCollected?'收藏成功':'取消收藏';
wx.showToast({
title,
icon:'success'
});
4. 本地数据存储
- wx.setStorage
- 将数据存储在本地缓存中指定的 key 中。会覆盖掉原来该 key 对应的内容。
- 除非用户主动删除或因存储空间原因被系统清理,否则数据都一直可用。
- 单个 key 允许存储的最大数据长度为 1MB,所有数据存储上限为 10MB。
参数
属性 | 类型 | 说明 |
---|---|---|
key | string | 本地缓存中指定的 key |
success | function | 接口调用成功的回调函数 |
fail | function | 接口调用失败的回调函数 |
complete | function | 接口调用结束的回调函数(调用成功、失败都会执行) |
- wx.getStorage
- 从本地缓存中异步获取指定 key 的内容
参数
属性 | 类型 | 说明 |
---|---|---|
key | string | 本地缓存中指定的 key |
success | function | 接口调用成功的回调函数 |
fail | function | 接口调用失败的回调函数 |
complete | function | 接口调用结束的回调函数(调用成功、失败都会执行) |
// 缓存数据到本地
// {1: true, 2: false} 依靠下标获取不同数据
let {index} = this.data;
// 不可行,会覆盖之前的状态
// let obj = {}; // {0: true, 2: true}
wx,wx.getStorage({
key: 'isCollected',
success: (datas) => {
// console.log(datas, typeof datas);
let obj = datas.data;
obj[index] = isCollected;
wx.setStorage({
key: 'isCollected',
data: obj,
success: () => {
}
})
},
})
5. 判断用户是否收藏
- wx.getStorageSync(string key)
参数
- string key
- 本地缓存中指定的 key
返回值
- any data
- key对应的内容
// 根据本地缓存的数据判断用户是否收藏当前的文章
let detailStorage = wx.getStorageSync('isCollected');
console.log(detailStorage);
if(!detailStorage){
// 在缓存中初始化空对象
wx.setStorageSync('isCollected', {});
}
// 判断用户是否收藏文章
if(detailStorage[index]){ // 收藏过
this.setData({
isCollected: true
})
}
6. 音乐播放器功能
1. 动态修改音乐图标
<image class="headImg" src="{{isMusicPlay?detailObj.music.coverImgUrl: detailObj.detail_img}}"></image>
<image catchtap="handleMusicPlay" class="musicImg"
src="{{isMusicPlay?'/images/music/music-start.png':'/images/music/music-stop.png'}}">
</image>
/**
* 页面的初始数据
*/
data: {
isMusicPlay: false
}
2. 音乐播放
-
wx.playBackgroundAudio
- 使用后台播放器播放音乐。对于微信客户端来说,只能同时有一个后台音乐在播放。当用户离开小程序后,音乐将暂停播放;
- 当用户在其他小程序占用了音乐播放器,原有小程序内的音乐将停止播放。
-
参数
属性 | 类型 | 说明 |
---|---|---|
dataUrl | string | 音乐链接,目前支持的格式有 m4a, aac, mp3, wav |
title | string | 音乐标题 |
coverImgUrl | string | 封面URL |
success | function | 接口调用成功的回调函数 |
fail | function | 接口调用失败的回调函数 |
complete | function | 接口调用结束的回调函数(调用成功、失败都会执行) |
3. 音乐暂停
-
wx.pauseBackgroundAudio
- 暂停播放音乐
-
参数
属性 | 类型 | 说明 |
---|---|---|
success | function | 接口调用成功的回调函数 |
fail | function | 接口调用失败的回调函数 |
complete | function | 接口调用结束的回调函数(调用成功、失败都会执行) |
代码
// 音乐播放
handleMusicPlay(){
// 处理音乐播放
let isMusicPlay = !this.data.isMusicPlay;
// 更新数据
this.setData({
isMusicPlay
});
// 控制音乐播放
if(isMusicPlay){
// 播放音乐
let {dataUrl,title} = this.data.detailObj.music; //获取音乐数据
wx.playBackgroundAudio({
dataUrl,
title
})
}else{
// 暂停音乐
wx.pauseBackgroundAudio({
})
}
}
4. 音乐监听
-
wx.onBackgroundAudioStop(function callback)
- 监听音乐停止事件
-
wx.onBackgroundAudioPlay(function callback)
- 监听音乐播放事件
-
wx.onBackgroundAudioPause(function callback)
- 监听音乐暂停事件
// 监听音乐播放
wx.onBackgroundAudioPlay(() => {
// 修改isMusicPlay状态值
this.setData({
isMusicPlay: true
});
// 修改appDatas中的数据
appDatas.data.isPlay = true;
appDatas.data.pageIndex = index;
})
// 监听音乐暂停
wx.onBackgroundAudioPause(() => {
// 修改isMusicPlay状态值
this.setData({
isMusicPlay: false
});
// 修改appDatas中的数据
appDatas.data.isPlay = true;
// appDatas.data.pageIndex = index;
})
5. 判断音乐是否在播放
App.js
App({
data: {
isPlay: false,
pageIndex: null
}
})
detail.js
- 引用App.js中的数据
// 引用App.js中的数据
let appDatas = getApp();
console.log(appDatas, typeof appDatas);
- 判断音乐是否在播放
// 判断音乐是否在播放
if(appDatas.data.isPlay && appDatas.data.pageIndex === index){
// 修改isMusicPlay状态值
this.setData({
isMusicPlay: true
});
}
7. 实现分享功能
- wx.showActionSheet
- 显示操作菜单
参数
属性 | 类型 | 说明 |
---|---|---|
itemList | Array.<string> | 按钮的文字数组,数组长度最大为 6 |
itemColor | string | 按钮的文字颜色 |
success | function | 接口调用成功的回调函数 |
fail | function | 接口调用失败的回调函数 |
complete | function | 接口调用结束的回调函数(调用成功、失败都会执行) |
代码
// 处理点击分享功能
handleShare(){
wx.showActionSheet({
itemList: [
'分享到朋友圈','分享到qq','分享到微博'
],
})
}
8. TabBar 功能
如果小程序是一个多 tab 应用(客户端窗口的底部或顶部有 tab 栏可以切换页面),可以通过 tabBar 配置项指定 tab 栏的表现,以及 tab 切换时显示的对应页面。
属性 | 类型 | 描述 |
---|---|---|
color | HexColor | tab 上的文字默认颜色,仅支持十六进制颜色 |
selectedColor | HexColor | tab 上的文字选中时的颜色,仅支持十六进制颜色 |
backgroundColor | HexColor | tab 的背景色,仅支持十六进制颜色 |
borderStyle | string | tabbar 上边框的颜色, 仅支持 black / white |
list | Array | tab 的列表,详见 list 属性说明,最少 2 个、最多 5 个 tab |
position | string | tabBar 的位置,仅支持 bottom / top |
custom | boolean | 自定义 tabBar,见详情 |
其中 list 接受一个数组,只能配置最少 2 个、最多 5 个 tab。tab 按数组的顺序排序,每个项都是一个对象,其属性值如下:
属性 | 类型 | 说明 |
---|---|---|
pagePath | string | 页面路径,必须在 pages 中先定义 |
text | string | tab 上按钮文字 |
iconPath | string | 图片路径,icon 大小限制为 40kb,建议尺寸为 81px * 81px,不支持网络图片。当 position 为 top 时,不显示 icon。 |
selectedIconPath | string | 选中时的图片路径,icon 大小限制为 40kb,建议尺寸为 81px * 81px,不支持网络图片。当 position 为 top 时,不显示 icon。 |
代码
"tabBar": {
"position": "bottom",
"list": [
{
"pagePath": "pages/list/list",
"text": "文与字",
"iconPath": "/images/tab/yuedu.png",
"selectedIconPath": "/images/tab/yuedu_hl.png"
},
{
"pagePath": "pages/movies/movies",
"text": "电影频道",
"iconPath": "/images/tab/dianying.png",
"selectedIconPath": "/images/tab/dianying_hl.png"
}
]
}
9. AJAX请求数据交互
- wx.request
- 发起 HTTPS 网络请求。
参数
属性 | 类型 | 说明 |
---|---|---|
url | string | 开发者服务器接口地址 |
data | string/object/ArrayBuffer | 请求的参数 |
header | Object | 设置请求的 header,header 中不能设置 Referer。content-type 默认为 application/json |
method | string | HTTP 请求方法 |
dataType | string | 返回的数据格式 |
responseType | string | 响应的数据类型 1.7.0 |
success | function | 接口调用成功的回调函数 |
fail | function | 接口调用失败的回调函数 |
complete | function | 接口调用结束的回调函数(调用成功、失败都会执行) |
代码
// 引入外部数据
const MOVIE_URL = 'http://t.yushu.im/v2/movie/top250';
onLoad: function (options) {
wx.request({
url: MOVIE_URL,
success: (response) => {
this.setData({
moviesArr: response.data.subjects
})
// 更新app数据
appDatas.data.moviesArr = response.data.subjects;
}
})
}
10. 电影详情页
1. 跳转到电影详情页
- navigator
- 页面链接
属性 | 类型 | 说明 |
---|---|---|
target | string | 在哪个目标上发生跳转,默认当前小程序 |
url | string | 当前小程序内的跳转链接 |
open-type | string navigate | 跳转方式 |
delta | number | 当 open-type 为 ‘navigateBack’ 时有效,表示回退的层数 |
app-id | string | 当target="miniProgram"时有效,要打开的小程序 appId |
path | string | 当target="miniProgram"时有效,打开的页面路径,如果为空则打开首页 |
extra-data | object | 当target="miniProgram"时有效,需要传递给目标小程序的数据,目标小程序可在 App.onLaunch(),App.onShow() 中获取到这份数据。 |
version | string | 当target="miniProgram"时有效,要打开的小程序版本 |
hover-class | string | 指定点击时的样式类,当hover-class="none"时,没有点击态效果 |
hover-stop-propagation | boolean | 指定是否阻止本节点的祖先节点出现点击态 |
hover-start-time | number | 按住后多久出现点击态,单位毫秒 |
hover-stay-time | number | 手指松开后点击态保留时间,单位毫秒 |
bindsuccess | string | 当target="miniProgram"时有效,跳转小程序成功 |
bindfail | string | 当target="miniProgram"时有效,跳转小程序失败 |
bindcomplete | string | 当target="miniProgram"时有效,跳转小程序完成 |
代码
<navigator url="/pages/movieDetail/movieDetail?index={{index}}"></navigator>
2. 接收数据
- movieDetail
<view class="movieDetailContainer">
<image class="movie_img" src='{{movieDetail.images.large}}'></image>
<text class="movie_name">{{movieDetail.original_title}}</text>
<view class="movie_detail">
<text>评分: {{movieDetail.rating.average}}</text>
<text>导演: {{movieDetail.directors[0].name}}</text>
<text>主演: {{movieDetail.casts[0].name}} {{movieDetail.casts[1].name}} {{movieDetail.casts[2].name}}</text>
</view>
<button>我要观影</button>
</view>
let appDatas = getApp();
console.log(appDatas);
Page({
/**
* 页面的初始数据
*/
data: {
movieDetail: {}
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
console.log(options);
this.setData({
movieDetail: appDatas.data.moviesArr[options.index]
})
}
})
7. 总结
1. 小程序优势
1. 成本低
- 对于微型企业或者商家来说,资金有限,开发一款APP的成本太高(运营维护,推广成本)
- 微信小程序基于微信平台上,有诸多流量入口,并且小程序的转发量也是相当高,对于这类企业和商家来说,小程序是最好的选择
2. 推广有效
- 企业的小程序正式上线以后,一定范围内的微信用户都可以看到你,并且店铺排名是根据用户离店铺的距离进行排名
- 用户使用过小程序以后会自动被放入列表,方便他们下次使用(商家很占优势)
3. 直接搜索
- 用户只要输入相关的关键字,点击搜索按钮,商家的店铺就会让用户在线体验商家提供的产品及服务。
- 用户会直接体验在线服务,而商家也自己的品牌宣传出去了
4. 体验流畅
- 微信目前是国内最大的社交网络平台
- 微信对小程序开放了大量的入口,小程序的流畅度与APP不相上下
- HTLM5页面经常会出现加载缓慢、加载超时、卡顿等现象,但是微信小程序功能和体验上是可以秒杀掉HTLM5页面