学习目标:
- 掌握小程序常用组件的使用
- 掌握腾讯视频插件的使用
- 掌握模板消息的使用
- 掌握背景音乐API、地图API的使用
1.开发前准备
1.1 项目展示
婚礼邀请函小程序由5个页面组成,分别是邀请函页面、照片页面、美好时光页面、婚礼地点页面、宾客信息页面。效果图如下:
下面针对5个页面的功能作简要介绍:
- 邀请函页面:新郎和新娘的电话、婚礼地点、婚礼时间。
- 照片页面:新郎和新娘的幸福照。
- 美好时光页面:采用视频的方式记录一对新人的相爱历程。
- 地图页面:通过导航查看婚礼地点的路线图。
- 宾客信息页面:参加婚礼的宾客填写个人信息,送一些祝福语等。
1.2 项目分析
婚礼邀请函项目目录结构
路 径 | 说 明 |
---|---|
app.js | 应用程序的逻辑文件 |
app.json | 应用程序的配置文件 |
app.wxss | 定义公共样式 |
pages/index/ | “邀请函”页面文件保存目录 |
pages/picture | “照片”页面文件保存目录 |
1.3 项目初始化
在微信开发者工具中创建一个空白项目。创建成功后,新建 app.json
文件,在该文件中定义本项目中的页面路径,代码如下:
{"pages": [
“pages/index/index”, // 邀请函页面
…
“pages/guest/guest“ // 宾客信息页面
]}
在app.json
文件中定义项目导航栏样式,代码如下:
"window": {
"backgroundTextStyle": "light",
"navigationBarBackgroundColor": "#ff4c91",
"navigationBarTextStyle": "white",
"enablePullDownRefresh": false
}
在app.json
文件中定义项目底部标签栏,代码示例如下:
"tabBar": {
"list": [
{
"pagePath": "pages/index/index",
"iconPath": "images/invite.png",
"selectedIconPath": "images/invite.png",
"text": "邀请函"
}…]
}
2. 邀请函页面
2.1 任务分析
邀请函页面的任务需求如下:
- 背景音乐播放:页面的右上角有一个背景音乐播放按钮,用于控制音乐播放状态,单击按钮播放音乐,再次- 单击按钮暂停音乐。
- 新人信息:页面中展示新娘和新郎的头像、姓名信息。
- 婚礼信息:页面展示婚礼时间及地点。
页面结构图:
2.2 背景音乐播放
功能控制音频播放,小程序切入后台时,如果音频当前处于播放状态,可以继续播放。index.wxml
<view class="player player-{{isPlayingMusic ? 'play' : 'pause'}}"
bindtap="play">
<image src="/images/music_icon.png" />
<image src="/images/music_play.png"/>
</view>
index.js
onReady: function () {
this.bgm = wx.getBackgroundAudioManager()
this.bgm.onCanplay(()=> {
this.bgm.pause()
})
this.bgm.src = this.music_url
},
index.js
play: function (e) {
if (this.data.isPlayingMusic) {
this.bgm.pause()
} else { this.bgm.play() }
this.setData({
isPlayingMusic:!this.data.isPlayingMusic })
},
效果如下:
2.3 页面结构和样式
index.wxml
<image class="content-gif" src= "/images/save_the_date.gif" />
<view class="content-title">邀请函</view>
<view class=“content-avatar">头像</view>
<view class="content-address">
<view>我们诚邀您来参加我们的婚礼</view>
<view>时间:2019年1月28日</view>
<view>地点:北京市海淀区XX路XX酒店</view>
</view>
效果如下:
页面内各元素的高度应满屏显示,为此,推荐使用viewport单位,即通过vw和vh表示宽度和高度,确保.content内部的元素高度加起来不超过100。
2.4 一键拨打电话
index.wxml
<view class="content-info">
<view bindtap="callGroom">
<view bindtap="callBride">
</view>
callGroom: function () {wx.makePhoneCall({})},
callBride: function () {wx.makePhoneCall({})}
3. 照片页面
3.1 任务分析
在本任务中,将会完成照片页面的开发,该页面采用纵向轮播的方式展示图片,可以通过单击指示面板的圆点切换到相对应的图片。
功能需求如下:
- 每一张轮播的图片都占满显示区域,滑动屏幕可以实现图片的纵向切换。
- 在右侧纵向显示指点面板,单击圆点可切换显示状态。
- 在用户无操作时,可以实现自动无缝轮播。
页面结构图:
3.2 实现纵向轮播图
picture.wxml
<swiper indicator-color="white" indicator-active-color="#ff4c91"
indicator-dots autoplay interval="3500" duration="1000" vertical circular>
<swiper-item wx:for="{{imgUrls}}" wx:key="*this">
<image src="{{item}}" mode="aspectFill" />
</swiper-item>
</swiper>
picture.wxss
swiper { height: 100vh; }
image { width: 100vw; height: 100vh; }
设置swiper组件属性:指示点默认颜色为白色,当前指示点颜色为 #ff4c91,轮播图方向通过 vertical设置为纵向,autoplay 开启自动轮播,circular 开启无缝轮播,duration 滑动动画时长为1秒,interval自动切换时间为3.5秒。
picture.js
data: {
imgUrls: [
'/images/timg1.jpg', '/images/timg2.jpg',
'/images/timg3.jpg', '/images/timg4.jpg'
]
}
效果图如下:
4. 美好时光页面
4.1 任务分析
在本任务中,将会完成美好时光页面的开发,该页面采用视频的方式来记录一对新人的难忘时光。
任务需求如下:
- 使用video组件实现视频播放。
- 使用腾讯视频插件实现视频播放。
项目结构图:
4.2 前导知识
video 组件常用属性
名称 | 类型 | 说明 |
---|---|---|
src | String | 视频的资源地址 |
loop | Boolean | 是否循环播放,默认为flase |
controls | Boolean | 是否显示默认播放控件(播放/暂停按钮、播放进度、时间),默认为true |
danmu-list | Object | 弹幕列表 |
danmu-btn | Boolean | 是否显示弹幕显示/隐藏按钮,只在初始化时有效,不能动态变更,默认为false |
enable-danmu | Boolean | 是否展示弹幕,只在初始化时有效,不能动态变更,默认为false |
autoplay | Boolean | 是否自动播放,默认为false |
poster | String | 视频封面的图片网络资源地址,如果controls属性值为false,则设置poster无效 |
bindplay | EventHandle | 当开始/继续播放时触发play事件 |
bindpause | EventHandle | 当暂停播放时触发pause事件 |
video.wxml
<video id="myVideo" src="{{src}}" danmu-list="{{danmuList}}"
enable-danmu danmu-btn controls></video>
<input bindblur="bindInputBlur" />
<button bindtap="bindSendDanmu">发送弹幕</button>
video.js
data: {
src: 'http://……/xxx.mp4',
danmuList: [{ text: '第 1s 出现的弹幕', color: '#ff0000', time: 1 },
{ text: '第 3s 出现的弹幕', color: '#ff00ff', time: 3 }] },
onReady: function () { this.videoContext = wx.createVideoContext('myVideo')}
关键函数:
bindInputBlur()函数
bindSendDanmu()函数
video.js
videoContext = null,
inputValue: '',
bindInputBlur: function (e) {
this.inputValue = e.detail.value
},
bindSendDanmu: function () {
this.videoContext.sendDanmu({
text: this.inputValue,
color: '#f90'
})
video组件示例图:37
VideoContext 对象常用方法如下:
名称 | 说明 |
---|---|
play() | 播放视频 |
pause() | 暂停视频 |
stop() | 停止视频 |
seek(number) | 跳转到制定的位置 |
plavbackRate(number) | 设置倍数播放 |
requestFullScreen | 进入全屏 |
exitFullScreen | 退出全屏 |
video.wxml
<button bindtap="bindButtonTap">获取视频</button>
video.js
bindButtonTap: function() {
wx.chooseVideo({
sourceType: ['album', 'camera'], // 视频选择的来源,相册和相机
maxDuration: 60, // 拍摄视频最长拍摄时间(秒)
camera: 'back', // 默认拉起的是前置(front)或者后置(back)摄像头
success: res => {// 成功时执行的回调函数
this.setData({src: res.tempFilePath// 选定视频的临时文件路径}) }})
},
4.3 编写页面结构和样式
video.wxml
<view class="video-list" wx:for="{{movieList}}" wx:key="user">
<view class="video-title">标题:{{item.title}}</view>
<view class="video-time">时间:{{item.create_time}}</view>
<video src="{{item.src}}" objectFit="fill"></video>
</view>
video.wxss
.video-list {
box-shadow: 0 8rpx 17rpx 0 rgba(7, 17, 27, 0.1);
margin: 10rpx 25rpx; padding: 20rpx; border-radius: 10rpx;
margin-bottom: 30rpx; background: #fff;
}
video.js
data: {
movieList: [{
create_time: '2018-7-25 19:55:54', title: '海边随拍',
src: 'http://……/xxx.mp4'
}, {
create_time: '2018-7-25 19:56:17', title: '勿忘心安',
src: 'http://……/xxx.mp4'
}] }
效果如下:
4.4 利用WXS增强页面功能
WXS应用场景举例:
页面中data
数据来自服务器端,但可能不适合直接显示到页面中,需要对数据进行转换后才能显示。
例如接收到的时间字段为时间戳。
假设在本项目中,视频列表数据是从服务器获取的,服务器返回的create_time
是一个时间戳,下面在pages/video/video.js
文件中模拟这一情况,将 create_time
改为时间戳
video.js
create_time:1532519777690,
wxs脚本语言嵌入代码
<wxs module="formatData">
module.exports = function(timestamp) {
var date = getDate(timestamp)
…
var h = date.getHours()
return y + '-' + m + '-' + d + ' ' + h}
</wxs>
5. 婚礼地点页面
5.1 任务分析
在本任务中,将会完成婚礼地点页面的开发,该页面会显示婚礼地点的地图,单击导航图标可以定位酒店位置,查看路线。
功能需求如下:
- 拾取到婚礼举办酒店的经纬度坐标。
- 利用map组件显示地图,并在婚礼地点放置markers覆盖物标记。
- 单击蓝色图标的标记点,通过wx.openLocation()调用微信内置地图查看位置。
婚礼地点运行效果图:
5.2 前导知识
map组件常用属性如下:
名称 | 类型 | 说明 |
---|---|---|
longitude | Number | 经度 |
latitude | Numberr | 纬度 |
scale | Number | 缩放级别,取值范围是5~18,默认16 |
markers | Array | 标记点 |
polyline | Array | 路线 |
circles | Array | 圆 |
show-location | Boolean | 显示有带方向的当前定位点 |
bindmarkertap | EvenHandle | 电机标记点时触发,会返回marker的id |
bindregionchange | EvenHandle | 视野发生变化时触发 |
bindtap | EvenHandle | 单击地图时触发 |
bindupdated | EvenHandle | 在地图渲染更新完成时触发 |
markers 标记点属性如下:
名称 | 类型 | 必填 | 说明 |
---|---|---|---|
id | Number | 否 | 标记点id,marker单击事件回调会返回此id |
longitude | Number | 是 | 经度,浮点数,范围-180~180 |
latitude | Number | 是 | 纬度,浮点数,范围-90~90 |
title | String | 否 | 标注点名 |
zIndex | Number | 否 | 显示层级 |
iconPath | String | 是 | 显示图标,使用项目目录下的图片路径 |
rotate | Number | 否 | 顺时针旋转的角度,范围0~360,默认0 |
alpha | Number | 否 | 透明度,范围0~2,默认为1(不透明) |
width | Number | 否 | 图片宽度,默认图片实际宽度 |
height | Number | 否 | 图片高度,默认物品实际高度 |
id | Number | 否 | 标记点id,marke单击事件回调会返回此id |
polyline 坐标点的属性如下:
名称 | 类型 | 必填 | 说明 |
---|---|---|---|
points | Array | 是 | 经纬度数组,如 [{latitude:0,longitude:0}] |
color | String | 否 | 线的颜色,8位十六进制表示,后两位表示alpha值,如:#000000AA |
width | Number | 否 | 线的宽度 |
dottedLine | Boolean | 否 | 是否虚线,默认为false |
circles 圆的属性如下:
名称 | 类型 | 必填 | 说明 |
---|---|---|---|
latitude | Number | 是 | 纬度,浮点数,范围-90~90 |
longitude | Number | 是 | 经度,浮点数,范围-180~180 |
color | String | 否 | 描边颜色8位十六进制表示,后两位表示alpha值,如:#0000000AA |
fillColor | String | 否 | 填充颜色8位十六进制表示,后两位表示alpha值,如:#0000000AA |
radius | Number | 是 | 半径 |
获取经纬度: map
组件需要给定经纬度,下面通过腾讯位置服务网站提供的坐标拾取器(https://lbs.qq.com/tool/getpoint/)来获取,示例图
如下:
map.wxml
<map latitude="40.060148" longitude="116.343219" scale="18" />
小程序提供了打开微信内置地图的API和定位用户位置的API,需要用户授权才能使用,也就是会自动提示用户“是否同意获取您的位置”,同意后即可获取。
map.wxml
<button bindtap="buttonTap">查看我的位置</button>
map.js
buttonTap: function() {
wx.getLocation({
type: 'gcj02',
success: function (res) {
wx.openLocation({
latitude: res.latitude,
longitude: res.longitude }) }
}) }
保存上述代码,在手机中运行测试,单击按钮后,得到效果图如下:
5.3 编写婚礼地点页面
map.wxml
<map latitude="{{latitude}}" longitude="{{longitude}}" markers="{{markers}}" bindmarkertap="markertap" />
map.wxss
map { width: 100vw; height: 100vh; }
map.js
data: {
latitude: 40.06021, longitude: 116.3433,
markers: [{
iconPath: '/images/navi.png', id: 0,
latitude: 40.06021, longitude: 116.3433, width: 50, height: 50
}] },
markertap: function() {
wx.openLocation({
latitude: this.data.latitude, longitude: this.data.longitude,
}) }
6.宾客信息页面
6.1 任务分析
在本任务中,将会完成宾客信息页面的开发,该页面提供了一个表单,用于填写来宾的信息,包括姓名、手机号、参加婚礼人数、新人祝福语。
功能需求如下:
- 为页面添加背景图。
- 当姓名、手机号所在文本框失去焦点时,触发失去焦点事件bindblur,对文本内容进行正则表达式校验,格式错误会给出友好的提示信息。
- 单击num(参加婚礼的人数)时,从底部弹出一个选择器,选择参加婚礼人数。
- 单击submit提交按钮,获取form表单数据,提交成功后会给出“成功”提示。
- 利用小程序中的模板消息机制,发送回复通知。
页面结构图:
6.2 前导知识
picker
组件是从底部弹起的滚动选择器,目前支持5种选择器,通过mode
属性来区分。
选择器类型如下:
- 默认:普通选择器(mode=“selector”) 。
- 多列选择器(mode=“multiSelector”)。
- 时间选择器(mode=“time”)。
- 日期选择器(mode=“date”)。
- 省市区选择器(mode=“region”)
guest.wxml
<picker range="{{array}}" value="{{index}}" bindchange="pickerChange">
<view>当前选择:{{array[index]}}(点我修改)</view>
</picker>
guest.js
data: { array: ['HTML', 'CSS', 'JavaScript', 'Photoshop'],
index: 1 },
pickerChange: function(e) {
this.setData({ index: e.detail.value })
},
range
属性表示显示在底部选择器的列表数组,数组中的每一个元素对应列表中的每一项;value
属性表示当前选择了range数
组中的某个元素的下标,默认值为0。bindchange
用于绑定change
事件,该事件会在value
改变时触发。
保存上述代码,运行程序测试,页面效果图如下:
模板消息 是在小程序中向用户发送消息的一种方式,其特点是必须按照小程序提供的模板来给用户发送消息,而且小程序在审核时,会对消息的标题、关键字等进行审查,以免功能被恶意使用。
使用场景如下:
-
支付提醒:
当支付成功时会推送给用户成功支付的信息,告知用户的订单详情。 -
到账提醒:
红包退还到账提醒、收款到账提醒等。 -
广告推送:
如订阅号推送、公众号推送等。
模板消息使用步骤:
进入小程序管理后台,单击左侧菜单中的 “模板消息”,
然后单击“添加”按钮添加模板:
在模板库中搜索模板,例如,搜索“婚礼”,示例图如下:
在搜索结果列表中,选择“婚礼请帖回复通知”,单击“选用”,即可选用该模板。选用成功后,可以查看该模板的ID和关键词:
模板消息使用注意事项:
-
实际开发中,模板消息的发送一般是由服务器主动发送给曾经使用过这个小程序的用户。
-
小程序本身不具备接收消息的功能,是由微信中的服务通知功能将消息转达给用户。
Q : 如何证明用户使用过某个小程序?
(必须满足以下其中一个条件):
-
支付:
用户在小程序内完成过支付行为,可允许开发者向用户在7天内推送有限条数的模板消息,1次支付可以发3条消息。 -
提交表单:
当用户在小程序内发生过提交表单行为,且该表单声明为要发模板消息,开发者需要向用户提供服务时,可允许开发者向用户在7天内推送有限条数的模板消息,1次提交表单可下发1条。
6.3 编写页面结构和样式
guest.wxml
<form bindsubmit="formSubmit" >
<input name="name" placeholder="输入您的姓名" />
<input name="phone" placeholder="输入您的手机号码" />
<picker name="num" bindchange="pickerChange" value="{{picker.index}}" range="{{picker.arr}}">参加婚礼人数:{{picker.arr[picker.index]}}</picker>
<input name="wish" placeholder="输入您的祝福语" />
<button form-type="submit">提交</button>
</form>
guest.js
data: {
picker: {
arr: ['0', '1', '2', '3', '4', '5', '6'],
index: 1
} },
pickerChange: function (e) {
this.setData({
'picker.index': e.detail.value
})
}
效果图如下:
6.4 表单验证
准备页面:pages/guest/guest.wxml
,绑定blur
事件,校验输入格式是否正确。
<view>
<input name="name" bindblur="nameChange"
placeholder-class="phcolor" placeholder="输入您的姓名" />
</view>
<view>
<input name="phone" bindblur="phoneChange"
placeholder-class="phcolor" placeholder="输入您的手机号码" />
</view>
pages/guest/guest.js
,编写check ()函数
check: function(data, reg, errMsg) {
if (!reg.test(data)) {
wx.showToast({title: errMsg, icon: 'none', duration: 1500})
return false
}
return true
}
pages/guest/guest.js
,编写checkName()
函数、checkPhone()
函数
checkName: function(data) {
var reg = /^[\u4E00-\u9FA5A-Za-z]+$/;
return this.check(data, reg, '姓名输入错误!')
},
checkPhone: function(data) {
var reg = /^(((13)|(15)|(17)|(18))\d{9})$/
return this.check(data, reg, '手机号码输入有误!')
},
pages/guest/guest.js
,编写事件处理函数nameChange()
、phoneChange()
函数。
nameChange: function (e) {
this.checkName(e.detail.value)
},
phoneChange: function (e) {
this.checkPhone(e.detail.value)
},
pages/guest/guest.js
,编写提交表单事件formSubmit()
函数。
formSubmit: function(e) {
var name = e.detail.value.name
var phone = e.detail.value.phone
if (this.checkName(name) && this.checkPhone(phone)) {
// 在此处可编写代码将e.detail.value提交到服务器
wx.showToast({title: '提交成功', icon: 'success', duration: 1500})
}
}
6.5 发送婚礼请帖回复通知
发送模板消息功能涉及到3个角色的参与,分别是小程序、服务器和微信接口,具体交互流程如下:
- 用户在小程序中填写表单,需要附加上
formId
和code
,提交给服务器。 - 服务器收到表单后,使用自己的
appid
、secret
和code
请求微信接口,获openid
。 - 服务器向用户发送模板消息,先用自己的
appid
、secret
请求微信接口,获取access_token
,然后使用access_token
和openid
、formId
,以及模板的id
和消息内容请求微信接口,发送模板消息。 - 微信接口将模板消息推送给用户,用户就会在微信的“服务通知”中看到消息。
pages/guest/guest.wxml
,为提交按钮设置report-submit
属性,生成formId
。
<button form-type="submit" report-submit>提交</button>
pages/guest/guest.js
,在formSubmit()
函数里,输出formId
。
formSubmit: function(e) {
console.log(e.detail.formId)
……(原有代码)
}
注意事项: 在微信开发者工具中formId
的输出结果为“the formId is a mock one”
,表示formId
是模拟的;在微信环境下运行小程序时,才可以获取到formId
。formId
控制台打印结果如下图:
服务器端代码:pages/guest/guest.js
文件
在Page()
函数后面编写server
对象,用于模拟服务器,与微信接口进行交互:
var server = {
appid: '', secret: '',
user: {openid: '', formId: ''}, // 用于保存用户的openid和formId
// 用于接收表单,调用this.getOpenid()根据code换取openid
post: function(data, success) {}, ...
}
在小程序管理后台获取appid
和secret
,appid
对应AppId
,secret
对应AppSecret
。
服务器端代码: pages/guest/guest.js
文件
在formSubmit()
表单验证成功的if
判断中,编写代码请求服务器。
if (this.checkName(name) && this.checkPhone(phone)) {
wx.login({
success: res => { // 将表单提交给服务器,传入formId和code
server.post({ formId: e.detail.formId, code: res.code }, ()=> {
wx.showToast({title: '提交成功!', icon: 'success', duration: 1500}) // 提交成功后,由服务器发送模板消息
server.sendTemplateMessage(res => { console.log('消息发送结果:', res.data)})
}) }
}) }
在server
对象中编写post()
方法。
post: function(data, success) {
console.log('收到客户端提交的数据:', data)
this.user.formId = data.formId
this.getOpenid(data.code, res => {
console.log('用户openid:' + res.data.openid)
this.user.openid = res.data.openid
success()
})
},
在server
对象中编写getOpenId()
方法。
// 用于根据code获取openid
getOpenid: function(code, success) {
wx.request({
url: 'https://api.weixin.qq.com/sns/jscode2session',
data: { appid: this.appid, secret: this.secret,
grant_type: 'authorization_code', js_code: code },
success: success
})
},
在server
对象中编写sendTemplateMessage()
函数。
// 用于发送模板消息
sendTemplateMessage: function(success) {
var user = this.user
var data = { touser: user.openid, page: 'index', form_id: user.formId,
template_id: 'vKLdyH1bJ8aXFZrZ-kgrYA58dcf8OCd5DDPN0QbXPhM',
data: { keyword1: { value: '王辉辉、张琳琳' },
keyword2: { value: '谢谢你的祝福' },
…}
}
在server
对象中编写sendTemplateMessage()
函数。
this.getAccessToken(res => {
var token = res.data.access_token
console.log('服务器access_token:' + token)
var url = 'https://api.weixin.qq.com/
cgi-bin/message/wxopen/template/send?
access_token=' + token
wx.request({ url: url, method: 'post',
data: data, success: success })
})
},
在server
对象中编写getAccessToken()
函数。
// 用于获取access_token
getAccessToken: function(success) {
var url = 'https://api.weixin.qq.com/
cgi-bin/token?
grant_type=client_credential&appid=' + this.appid
+ '&secret=' + this.secret
wx.request({ url: url, success: success })
}
宾客信息页面提交表单后就会收到微信的提示信息“婚礼请帖回复通知”:
总 结
本项目通过一个婚礼邀请函的设计,讲解了小程序中的 标签页切换、背景音乐API、拨打电话API、video组件、腾讯视频插件、map组件、地图定位API、WXS、picker组件,以及模板消息的使用。能够熟练在小程序中灵活使用各种组件完成具体功能,掌握音频播放、视频播放、地图定位、模板消息等常见开发需求的实现。
成果展示
婚礼邀请函小程序
划重点 项目源码地址 和 婚礼邀请函项目教学视频获取 密码
本人在CSDN论坛写的所有文章,仅针对本人自身做学习记录,不全面,不详细,还请见谅!文章来源:https://www.toymoban.com/news/detail-436573.html
如果有小伙伴需要详细解答或完整学习资源, 欢迎加入我的知识星球「Naiva的知识问答社区」文章来源地址https://www.toymoban.com/news/detail-436573.html
到了这里,关于微信小程序 #项目笔记# | 从0到1实现婚礼邀请函小程序的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!