10分鐘入門 - 微信小程式開發
註冊微信小程式
如果你還沒有微信公眾平臺的賬號,請先進入微信公眾平臺首頁,點選 “立即註冊” 按鈕進行註冊。註冊的賬號型別可以是訂閱號、服務號、小程式以及企業微信,我們選擇 “小程式” 即可。
接著填寫賬號資訊,需要注意的是,填寫的郵箱必須是未被微信公眾平臺註冊、未被個人微訊號繫結的郵箱,而且每個郵箱僅能申請一個小程式。
啟用郵箱之後,選擇主體型別為 “個人型別”,並按要求登記主體資訊。主體資訊提交後不可修改,該主體將成為你使用微信公眾平臺各項服務和功能的唯一法律主體與締約主體,在後續開通其他業務功能時不得變更或修改。
一切 OK 就可以直接進入小程式的管理平臺了。如果直接跳轉失敗,也可以從微信公眾平臺上手動登入。填寫小程式的基本資訊,包括名稱、圖示、描述等。提交成功之後,再新增開發者。開發者預設為管理員,我們也可以從這裡新增繫結開發者,這是管理員才有許可權的操作。
然後在左側導航欄點選 “設定”,找到開發設定,獲得小程式的 AppID。
微信開發者工具
下載微信web開發者工具,根據自己的作業系統下載對應的安裝包進行安裝即可。
開啟開發者工具,用微信掃碼登入開發者工具,準備開發你的第一個小程式吧!
第一個小程式
新建專案
開啟開發者工具,選擇 “小程式專案”,點選右下角的 “+” 新建專案。
選擇一個空的資料夾作為專案目錄,填入剛剛的 AppID,再填寫一個專案名稱,比如我這裡叫做 GoZeroWaster。點選 “確定” 進入工具主介面。
專案目錄結構
微信小程式的基本檔案構造和專案目錄結構說明如下:
.
├── app.js # 小程式的邏輯檔案
├── app.json # 小程式的配置檔案
├── app.wxss # 全域性公共樣式檔案
├── pages # 存放小程式的各個頁面
│ ├── index # index頁面
│ │ ├── index.js # 頁面邏輯
│ │ ├── index.wxml # 頁面結構
│ │ └── index.wxss # 頁面樣式表
│ └── logs # logs頁面
│ ├── logs.js # 頁面邏輯
│ ├── logs.json # 頁面配置
│ ├── logs.wxml # 頁面結構
│ └── logs.wxss # 頁面樣式表
├── project.config.json
└── utils
└── util.js
根目錄下有3個檔案:app.js、app.json、app.wxss,小程式必須有這3個描述 APP 的檔案,並放在根目錄下。這3個是應用程式級別的檔案,與之平行的還有一個 pages 資料夾,用來存放小程式的各個頁面。
我們可以和 web 前端開發技術做個類比:
- wxml 類似於 HTML 檔案,用來編寫頁面的標籤和骨架,但裡面只能用小程式自己封裝的元件;
- wxss 類似於 CSS 檔案,用來編寫頁面樣式,只是把 css 檔案換成了 wxss 檔案;
- js 檔案類似於前端程式設計中的 JavaScript 檔案,用來編寫小程式的頁面邏輯;
- json 檔案用來配置頁面的樣式和行為。
目標成果
我們先來看看最終的目標和成果,很簡單,一共兩頁:
(為了讓廣大程式設計師也能保護環境和熱愛生活,我特意選了 “零垃圾生活” 主題來做 Demo)
步驟分解
Demo 程式碼下載:https://gitee.com/luhuadong/Web_Learning/tree/master/WeChat/GoZeroWaster
分解目標成果:
- 個人中心
- 生活指南
- 模擬彈窗
- 預覽圖片
頁頭頁尾
在目標成果預覽中我們看到,兩個頁面都有共同的部分 —— 頁頭和頁尾。所以在構建頁面內容之前,我們先把頁頭和頁尾處理好。我們很容易猜到,這兩部分屬於小程式的全域性配置,因此需要修改 app.json 檔案。
最初的內容如下:
{
"pages":[
"pages/index/index",
"pages/logs/logs"
],
"window":{
"backgroundTextStyle": "light",
"navigationBarBackgroundColor": "#fff",
"navigationBarTitleText": "WeChat",
"navigationBarTextStyle": "balack"
}
}
pages 屬性用來設定頁面路徑,它是一個數組,每一項都是字串來指定小程式由哪些頁面組成。陣列的第一項代表小程式的初始頁面。小程式中新增或減少頁面,都需要對 pages 陣列進行修改。
window 屬性用於設定小程式的狀態列、導航條、標題、視窗背景色。
我們把頁頭的標題和顏色修改一下,頁尾部分我們做一個 tab 欄來切換頁面,這個屬性叫做 tabBar,程式碼如下:
{
"pages":[
"pages/index/index",
"pages/logs/logs"
],
"window":{
"backgroundTextStyle":"light",
"navigationBarBackgroundColor": "#2f2f8f",
"navigationBarTitleText": "GoZeroWaste",
"navigationBarTextStyle":"white"
},
"tabBar":{
"color": "#bfc1ab",
"selectedColor": "#13b11c",
"backgroundColor": "#1f1f4f",
"list": [
{
"pagePath": "pages/index/index",
"iconPath": "image/icon_component.png",
"selectedIconPath": "image/icon_component_HL.png",
"text": "個人中心"
},
{
"pagePath": "pages/details/details",
"iconPath": "image/icon_API.png",
"selectedIconPath": "image/icon_API_HL.png",
"text": "生活指南"
}
]
}
}
(所用到的圖片放在專案的 image 目錄,你也可以使用自己的圖片)
這裡用到幾個 tabBar 的屬性是 color、selectedColor、backgroundColor 和 list,list 是一個數組,主要用於設定導航的路徑。
CTRL + S 儲存之後,模擬器就會自動重新整理,馬上可以看到效果。
個人中心
簡單起見,我們就在 pages/index 目錄下實現 “個人中心” 頁面好了。雙擊開啟 index.wxml,初始內容如下:
<!--index.wxml-->
<view class="container">
<view class="userinfo">
<button wx:if="{{!hasUserInfo && canIUse}}" open-type="getUserInfo" bindgetuserinfo="getUserInfo"> 獲取頭像暱稱 </button>
<block wx:else>
<image bindtap="bindViewTap" class="userinfo-avatar" src="{{userInfo.avatarUrl}}" background-size="cover"></image>
<text class="userinfo-nickname">{{userInfo.nickName}}</text>
</block>
</view>
<view class="usermotto">
<text class="user-motto">{{motto}}</text>
</view>
</view>
這裡已經有一些程式碼了,雖然現在可能還看不懂,但我們知道,這就是現在頁面的原始碼。我們把 “Hello World” 部分註釋掉,增加我們希望顯示的內容:
<!--index.wxml-->
<view class="container">
<view class="userinfo">
<button wx:if="{{!hasUserInfo && canIUse}}" open-type="getUserInfo" bindgetuserinfo="getUserInfo"> 獲取頭像暱稱 </button>
<block wx:else>
<image bindtap="bindViewTap" class="userinfo-avatar" src="{{userInfo.avatarUrl}}" background-size="cover"></image>
<text class="userinfo-nickname">{{userInfo.nickName}}</text>
</block>
</view>
<!-- <view class="usermotto">
<text class="user-motto">{{motto}}</text>
</view> -->
<view class="ID_Badge">
<view>
<text class="ID_info">{{company}}</text>
</view>
<view>
<text class='ID_info'>{{position}}</text>
</view>
<view>
<text class='ID_info'>{{lesson}}</text>
</view>
</view>
</view>
這裡分別使用 {{company}}
、{{position}}
和 {{lesson}}
作為佔位符,用法類似於 Django 的模板語言。當然也可以直接用相應的字元來替換它,只不過我們想沿用 {{motto}}
的做法,讓你知道在哪裡修改這些資料。沒錯,就是在 index.js 檔案:
Page({
data: {
motto: 'Hello World',
company: "GoZeroWaste",
lesson: "21天零垃圾生活指南",
position: "垃圾魔法師",
/* ... */
},
wxml 檔案中的 <view>
元件類似於網頁開發中的 <div>
,而 <text>
元件是用來寫文字的,需要注意的是 <text/>
元件內只支援 <text/>
巢狀。當然,可用用 <image>
插入圖片,圖片要儲存到 image 目錄,否則在測試的時候是無法上傳的。
<view class="ID_Badge">
<!-- 省略 -->
<view>
<text class='ID_info'>{{lesson}}</text>
</view>
<view>
<image class='pic' mode='widthFix' src='../../image/GoZeroWaste.jpg'></image>
</view>
</view>
mode=‘widthFix’ 表示以寬度不變,高度自動變化,保持原圖寬高比不變的方式進行縮放以適應螢幕大小。
接下來還需要修改 index.wxss 檔案來設定樣式:
/**index.wxss**/
.userinfo {
display: flex;
flex-direction: column;
align-items: center;
}
.userinfo-avatar {
width: 128rpx;
height: 128rpx;
margin: 20rpx;
border-radius: 50%;
}
.userinfo-nickname {
color: #aaa;
}
.usermotto {
margin-top: 200px;
}
.ID_Badge {
padding-top: 20rpx;
color: blue;
}
.ID_info {
display: flex;
flex-direction: column;
align-items: center;
}
.pics {
width: 400rpx;
}
儲存重新整理,“個人中心” 頁面就完成了。
生活指南
原來的專案中 pages 目錄下只有 index 和 logs 兩個目錄,因此我們還需要為第二個頁面建立一個目錄。
建立頁面有兩種方法:
- 在目錄結構的 pages 圖表上,新建目錄,然後在目錄下逐一建立頁面構成檔案
- 在 app.json 下,直接新增
建議採用第二種方法,修改 app.json 檔案:
{
"pages":[
"pages/index/index",
"pages/logs/logs",
"pages/details/details"
],
儲存重新整理之後就會發現,目錄結構裡自動建立了這一頁。對應的,也要修改 app.json 中的 tabBar 的連結(實際上我們已經做了):
{
"pagePath": "pages/details/details",
"iconPath": "image/icon_API.png",
"selectedIconPath": "image/icon_API_HL.png",
"text": "生活指南"
}
然後修改 details.wxml 設定這一頁的標題:
<!--pages/details/details.wxml-->
<view>
<view class='title'>
<text>21天零垃圾生活指南</text>
</view>
</view>
修改 details.wxss 設定樣式:
/* pages/details/details.wxss */
.title {
display: flex;
flex-direction: column;
align-items: center;
margin-top: 40rpx;
margin-bottom: 40rpx;
font-size: 40rpx;
}
這個頁面是一個列表展示的頁面,我們先在 details.js 檔案中準備好資料:
// pages/details/details.js
Page({
/**
* 頁面的初始資料
*/
data: {
showModalStatus: false,
list: [
{
id: 0,
name : "寫一篇《垃圾日記》",
introduce: "零垃圾並不是一項巨集大的工程,而是由日常生活中一個個小小的習慣和選擇組成的。最難的,是邁出第一步。",
src: '../../image/day01.jpg',
showModalStatus: false,
catalog: [
{ section: "1. xxx" },
{ section: "2. xxx" },
{ section: "3. xxx" },
{ section: "4. xxx" },
]
},
{
id: 1,
name: "帶上自己的購物袋",
introduce: "在我們家,當時垃圾桶裡最多的就是塑料袋,而這些袋子跟著我回家後,都幾乎難逃被丟進垃圾桶的命運。",
src: '../../image/day02.jpg',
showModalStatus: false,
catalog: [
{ section: "1. xxx" },
{ section: "2. xxx" },
{ section: "3. xxx" },
{ section: "4. xxx" },
]
},
/* 省略 */
]
},
接下來我們要使用列表渲染(wx:for
)的方法將這些資料繫結一個數組,並在頁面上重複渲染。修改 details.wxml 檔案:
<view>
<view wx:for="{{list}}" wx:key="id" >
<view class="lesson" id="{{item.id}}">
<image class="lessonPic" mode='aspectFit' src="{{item.src}}"></image>
<view class="lessonName">{{item.name}}</view>
<view class="lessonIntroduce">{{item.introduce}}</view>
</view>
</view>
</view>
預設陣列的當前項的下標變數名預設為 index,陣列當前項的變數名預設為 item。
修改 details.wxss 檔案新增樣式:
.lesson {
height: 190rpx;
padding-left: 20rpx;
}
.lessonPic {
position: absolute;
height: 150rpx;
width: 150rpx;
}
.lessonName {
position: absolute;
margin-left: 220rpx;
font-size: 35rpx;
}
.lessonIntroduce {
position: absolute;
margin-left: 220rpx;
margin-top: 60rpx;
margin-right: 20rpx;
color: rgb(185, 161, 161);
font-size: 28rpx;
}
好啦,第二個頁面也完成了。
模擬彈窗
接下來我們要在 “生活指南” 頁面模擬一個彈窗的效果,正常的時候不顯示,只有在點選的時候才出現,摁下面的 “確定” 就會消失。
完了實現這個功能,我們要在元件中繫結一個事件處理函式 bindtap,點選該元件的時候,小程式會在該頁面對應的 Page 中找到相應的事件處理函式。
我們先在 details.js 中為每一列資料裡引入一個 boolean 變數 showModalStatus 來描述對應的彈窗狀態,並且初始值為 false,表示不顯示。同時外層也增加一個初始值為 false 的 showModalStatus 變數實現遮罩效果。如下:
data: {
showModalStatus: false,
list: [
{
id: 0,
name : "寫一篇《垃圾日記》",
introduce: "零垃圾並不是一項巨集大的工程,而是由日常生活中一個個小小的習慣和選擇組成的。最難的,是邁出第一步。",
src: '../../image/day01.jpg',
showModalStatus: false,
catalog: [
{ section: "1. xxx" },
{ section: "2. xxx" },
{ section: "3. xxx" },
{ section: "4. xxx" },
]
},
然後在 details.wxml 中插入彈窗,並用條件渲染(wx:if
)來判斷是否渲染(顯示)彈窗。同時為每一個 item 新增 data-statu 來表示彈窗的狀態。如下:
<view>
<view wx:for="{{list}}" wx:key="id" >
<view class="lesson" bindtap='powerDrawer' data-statu='open' id="{{item.id}}">
<image class="lessonPic" mode='aspectFit' src="{{item.src}}"></image>
<view class="lessonName">{{item.name}}</view>
<view class="lessonIntroduce">{{item.introduce}}</view>
</view>
<!-- 彈窗 -->
<view class='drawer_box' wx:if='{{item.showModalStatus}}' id='{{item.id}}'>
<view class="title">{{item.name}}</view>
<view class='drawer_content'>
<view class='title' wx:for='{{item.catalog}}' wx:for-item='catalog' wx:key='id'>
{{catalog.section}}
</view>
</view>
<!-- 確定按鈕 -->
<view class='btn_ok' bindtap='powerDrawer' data-statu='close' id='{{item.id}}'>確定</view>
</view>
</view>
<!-- 遮罩層 -->
<view class='drawer_screen' data-statu='close' wx:if='{{showModalStatus}}'></view>
</view>
在 details.js 新增 powerDrawer 事件處理,包括顯示和關閉事件:
powerDrawer: function (e) {
console.log("clicked");
var currentStatu = e.currentTarget.dataset.statu;
var index = e.