Project Overview
This wedding invitation mini program consists of five distinct pages: the main invitation view, a photo gallery, a video memories section, a venue map, and a guest response form. Below is a brief introduction to the functionality of each section:
- Invitation View: Displays the couple's avatars, names, wedding date, time, and location, alongside quick-dial buttons for the bride and groom.
- Photo Gallery: Showcases happy moments of the couple using a vertical image carousel.
- Memories Section: Utilizes video components to documnet the couple's journey.
- Venue Map: Integrates maps to help guests navigate to the wedding location.
- Guest Form: Allows attendees to RSVP, select the number of guests, and leave blessings.
Project Initialization
Start by creating a blank project in the WeChat Developer Tools. You need to define the page routes and global styles in app.json.
{
"pages": [
"pages/home/home",
"pages/gallery/gallery",
"pages/memories/memories",
"pages/location/location",
"pages/rsvp/rsvp"
],
"window": {
"navigationBarBackgroundColor": "#ff4c91",
"navigationBarTitleText": "Wedding Invite",
"navigationBarTextStyle": "white",
"backgroundTextStyle": "light"
},
"tabBar": {
"list": [
{
"pagePath": "pages/home/home",
"text": "Invitation",
"iconPath": "assets/icon_invite.png",
"selectedIconPath": "assets/icon_invite_active.png"
}
// ... other tab items
]
}
}
Invitation Page (Home)
Background Music Control
The page features a toggle button in the corner to play or pause background music. The logic checks the current state and trigggers the appropriate audio method.
home.wxml
<view class="audio-control {{isMusicOn ? 'playing' : 'paused'}}" bindtap="toggleAudio">
<image src="/assets/music.png" />
</view>
home.js
toggleAudio: function () {
if (this.data.isMusicOn) {
this.backgroundAudio.pause();
} else {
this.backgroundAudio.play();
}
this.setData({ isMusicOn: !this.data.isMusicOn });
}
Quick Dial Feature
Implement one-tap calling using the wx.makePhoneCall API.
contactGroom: function () {
wx.makePhoneCall({ phoneNumber: '13800138000' })
},
contactBride: function () {
wx.makePhoneCall({ phoneNumber: '13800138001' })
}
Photo Gallery (Vertical Carousel)
The gallery uses a vertical swiper component that auto-plays and loops through images.
gallery.wxml
<swiper vertical circular autoplay interval="3000" duration="500" indicator-dots indicator-color="#fff" indicator-active-color="#e91e63">
<swiper-item wx:for="{{photoList}}" wx:key="id">
<image src="{{item.src}}" mode="aspectFill" />
</swiper-item>
</swiper>
gallery.js
data: {
photoList: [
{ id: 1, src: '/images/pic_01.jpg' },
{ id: 2, src: '/images/pic_02.jpg' },
{ id: 3, src: '/images/pic_03.jpg' }
]
}
Memories Page (Video Integration)
This section uses the <video> component. It also demonstrates how to handle timestamp formatting using WXS (WeiXin Script) for dynamic data display.
memories.wxml
<wxs module="dateFilter">
module.exports = function(ts) {
var d = getDate(ts);
return d.getFullYear() + '-' + (d.getMonth() + 1) + '-' + d.getDate();
}
</wxs>
<view class="video-container" wx:for="{{videoList}}" wx:key="id">
<view class="title">{{item.title}}</view>
<view class="date">Date: {{dateFilter(item.timestamp)}}</view>
<video src="{{item.url}}" controls></video>
</view>
memories.js
data: {
videoList: [
{ id: 1, title: 'Seaside Memories', timestamp: 1532519777690, url: 'http://example.com/video1.mp4' }
]
}
Wedding Location (Map Integration)
Use the <map> component to mark the venue. Clicking the marker opens the native WeChat map for navigation.
location.wxml
<map longitude="{{lng}}" latitude="{{lat}}" scale="16" markers="{{markers}}" bindmarkertap="openNavigation"></map>
location.js
data: {
lat: 40.06021,
lng: 116.3433,
markers: [{
id: 1,
latitude: 40.06021,
longitude: 116.3433,
iconPath: '/assets/marker.png',
width: 40,
height: 40
}]
},
openNavigation: function() {
wx.openLocation({
latitude: this.data.lat,
longitude: this.data.lng,
name: 'Wedding Venue',
address: 'Some Street, Haidian District'
});
}
Guest RSVP Form
Form Structure and Picker
The form collects user info. A picker component is used to select the number of attendees.
rsvp.wxml
<form bindsubmit="submitForm">
<input name="username" placeholder="Your Name" bindblur="validateName" />
<input name="mobile" placeholder="Phone Number" bindblur="validatePhone" />
<picker bindchange="changeCount" value="{{countIndex}}" range="{{countArray}}">
<view>Guests: {{countArray[countIndex]}}</view>
</picker>
<input name="blessing" placeholder="Leave a blessing" />
<button form-type="submit">Submit RSVP</button>
</form>
Validation Logic
Validate the name and phone number using regular expressions when the input loses focus.
validateName: function(e) {
const nameReg = /^[\u4E00-\u9FA5A-Za-z]+$/;
if (!nameReg.test(e.detail.value)) {
wx.showToast({ title: 'Invalid Name', icon: 'none' });
}
},
validatePhone: function(e) {
const phoneReg = /^1[3-9]\d{9}$/;
if (!phoneReg.test(e.detail.value)) {
wx.showToast({ title: 'Invalid Phone Number', icon: 'none' });
}
}
Subscription Messages
To send a notiifcation after submission, request permission using wx.requestSubscribeMessage and exchange the login code for an openid via the backend.
submitForm: function(e) {
wx.login({
success: (loginRes) => {
// Simulated server request to exchange code for openid and send message
wx.request({
url: 'https://your-api.com/send-rsvp',
data: {
code: loginRes.code,
formDetails: e.detail.value
},
success: () => {
wx.showToast({ title: 'RSVP Successful!', icon: 'success' });
}
});
}
});
}