微信小程式賬號註冊
- 訪問【微信公眾平臺】,註冊一個微信小程式賬號
https://mp.weixin.qq.com/
-
申請賬號需要準備一個郵箱,該郵箱要求:
- 未被微信公眾平臺註冊
- 未被微信開放平臺註冊
- 未被個人微訊號繫結過
- 如果被繫結了需要解綁 或 使用其他郵箱
-
獲取 小程式id
AppID(小程式ID) wxd63f21a664e8009b
AppSecret(小程式金鑰) 513e6cd6ea1a2692c9727004af729f1c
建立專案
- 下載【微信開發工具】--需要聯網才能使用
https://developers.weixin.qq.com/miniprogram/dev/devtools/stable.html
- 本地開發支援http
小程式預設只支援https,我們需要做如下配置,讓其支援http,方便我們本地開發
專案目錄結構
介紹
# 1 專案主配置檔案
專案主配置檔案必須放到專案的根目錄下,控制整個專案
- app.js: 小程式入口檔案
- app.json:小程式的全域性配置檔案
- app.wxss:小程式的全域性樣式
-app.js 和 app.json 檔案是必須的,不能沒有
# 2 頁面檔案
小程式有一個個頁面,每個頁面所需的檔案,都存放在 pages 目錄下,一個頁面一個資料夾
-xx.js: 頁面邏輯 js程式碼存放位置
-xx.wxml:頁面結構 類html檔案存放位置
-xx.wxss:頁面樣式 css存放位置
-xx.json:小頁面配置
-xx.js 檔案和 xx.wxml 檔案是必須的,不能沒有
# 3 相關配置文件
https://developers.weixin.qq.com/miniprogram/dev/reference/configuration/app.html
結構
├── components 【頁面中使用的元件】
├── pages 【頁面檔案目錄】
│ ├── index 【頁面】
│ │ ├── index.js 【頁面JS】
│ │ ├── index.json 【頁面配置】
│ │ ├── index.wxml 【頁面HTML】
│ │ └── index.wxss 【頁面CSS】
│ └── logs 【頁面】
│ ├── logs.js ...
│ ├── logs.json ...
│ ├── logs.wxml ...
│ └── logs.wxss ...
├── utils 【自定義工具】
│ └── utils.js 【功能的定義】
├── app.js 【全域性JS】
├── app.json 【全域性配置】
├── app.wxss 【全域性CSS】
├── project.config.json 【開發者工具預設配置】
├── project.private.config.json 【開發者工具使用者配置,在這裡修改,優先用這個,可以刪除】
├── .eslintrc.js 【ESlint語法檢查配置】
├── sitemap.json 【微信收錄頁面,用於搜尋,上線後,搜尋關鍵字就可以搜到我們】
常用元件
# 參考地址:
https://developers.weixin.qq.com/miniprogram/dev/component/
text,類似於span
<text>Justin</text>
view,類似於div
<view>
<view>Python山頂會</view>
<view>Justin</view>
<view>微信:616564099</view>
</view>
image,類似於img標籤
<image src="/images/1.png" style="width: 750rpx;height: 400rpx;"></image>
icon
<icon type="success" size='198rpx' color="red"/>
<icon type="download" size='198rpx' color="#ddd"/>
success, success_no_circle, info, warn, waiting, cancel, download, search, clear
跳轉,類似於a標籤
<navigator class="menu" url="/pages/login/login">
<label class="fa fa-superpowers" style="color:#32CD32"></label>
<view>登入</view>
</navigator>
繫結事件,在js中跳轉:
<view bindtap="clickMe" data-nid="123" >點我跳轉</view>
Page({
clickMe:function(e){
var nid = e.currentTarget.dataset.nid;
console.log(nid);
wx.navigateTo({
url: '/pages/login/login'
})
}
})
跳轉到其他頁面之後,可以在onLoad中獲取引數
wx.navigateTo({
url: '/pages/login/login?name=justin'
})
Page({
onLoad: function (options) {
console.log(options);
}
})
尺寸單位 和樣式
- rpx 可以根據不同的手機螢幕進行自動調整,自適應縮放
- 無論什麼手機--》螢幕寬度都是 750rpx
- 區域性樣式: xxx.wxss
- 全域性樣式: app.wxss
tabbar配置
"tabBar": {
"selectedColor": "#b4282d",
# 放置位置只有兩個,top:頂部;bottom:底部
"position": "bottom",
# list是陣列,裡面的tabbar至少2個至多5個
"list": [
{
# 頁面的路徑
"pagePath": "pages/index/index",
# 文字的內容
"text": "首頁",
# 預設圖示路徑
"iconPath": "images/home.png",
#選中的圖示路徑
"selectedIconPath": "images/home_select.png"
},
...
]
},
實現輪播圖 swiper+swiper-item
<swiper
autoplay
interval="2000"
indicator-dots
indicator-color="#00FF00"
indicator-active-color="#70DB93"
circular
>
<swiper-item>
<image src="/images/banner1.jpg" mode="widthFix"/>
</swiper-item>
<swiper-item>
<image src="/images/banner2.png" mode="widthFix"/>
</swiper-item>
<swiper-item>
<image src="/images/banner3.jpg" mode="widthFix"/>
</swiper-item>
</swiper>
引入向量圖示庫
https://www.iconfont.cn/
# 1 搜尋想要的圖示
-加入購物車
-在購物車中新增至專案
# 2 我的專案--專案設定--》開啟base64
# 3 選擇font class --》生成程式碼--》點選連結地址開啟
# 4 把開啟的連結地址內容複製到專案中
-static/css/iconfont.wxss
# 5 在app.wxss中引入
@import "/static/css/iconfont.wxss";
# 6 在想用圖示的位置,加入text元件
<text class="iconfont icon-anquan">
事件繫結
- bind:tab bindtab
# 1 方式一
<view bind:tab="showLog"></view>
# 2 方式二
<view bindtab="showLog"></view>
# 3 js中寫方法
showLog(){
console.log("我被點了")
}
阻止事件冒泡
catch:tap
<view style="height:300rpx;display: flex;justify-content: center;align-items: center; background-color: orange;" bind:tap="handleView">
<button type="primary" plain catch:tap="handleButton">阻止事件冒泡</button>
</view>
handleView() {
console.log("view被點了")
},
handleButton() {
console.log("button被點了")
},
事件物件和傳參
data-*方案
mark:自定義屬性
target :事件觸發者 :dataset data定義的屬性
currentTarget:事件繫結者 :dataset data定義的屬性
頁面跳轉
- 使用 navigator 元件實現跳轉
open-type :跳轉方式
navigate:保留當前頁面,跳轉到應用內的某個頁面。但是不能跳到 tabbar 頁面redirect: 關閉當前頁面,跳轉到應用內的某個頁面。但不能跳轉到 tabbar 頁面
switchTab:跳轉到 tabBar 頁面,並關閉其他所有非 tabBar 頁面
reLaunch:關閉所有頁面,開啟到應用內的某個頁面
navigateBack:關閉當前頁面,返回上一頁面或多級頁面
wxml語法
# 1 在頁面 xx.js 的 Page() 方法的 data 物件中進行宣告定義
# 2 在xx.wxml 中使用 {{}} 包裹,顯示資料
# 3 可以顯示如下,不能編寫js語句或js方法
-變數
-算數運算
-三元運算
-邏輯判斷
# 4 只是單純透過賦值,js中變數會變化,但是wxml中的頁面不會變化,沒有聯動效果,需要使用setData()方法修改
setData案例 修改物件
data: {
name: 'justin',
age: 19,
userinfo: {
name: 'qcc',
age: 99
}
},
handleChangeName() {
// 增加資料
this.setData({
'userinfo.hobby': '籃球'
})
// 修改資料
this.setData({
'userinfo.name': '彭于晏'
})
// 修改多個資料--》簡便方案--》展開運算子
// const userinfo = {
// ...this.data.userinfo,
// name: '新名字',
// hobby: '乒乓球'
// }
// this.setData({
// // userinfo:userinfo
// userinfo //簡寫形式
// })
// 修改多個資料--》簡便方案-->assign
const userinfo = Object.assign(this.data.userinfo, {
name: 'xxzz',
hobby: 'aa'
})
this.setData({
// userinfo:userinfo
userinfo //簡寫形式
})
//刪除資料-->單個
delete this.data.userinfo.name // 頁面刪除不了,需要用setData更新
this.setData({
userinfo:this.data.userinfo
})
//刪除資料-->多個--解構賦值
const {name,age,...res}=this.data.userinfo
this.setData({
userinfo:res
})
},
setData 修改陣列
data: {
names:['劉亦菲','迪麗熱巴','古力娜扎','馬爾扎哈']
},
handleChangeList(){
//1 增加再設定值
this.data.names.push('xxx')
this.setData({
names:this.data.names
})
// 1.2 透過陣列拼接
const newList=this.data.names.concat("aaa")
this.setData({
names:newList
})
// 1.3 透過解構賦值
const newList=[...this.data.names,"李白"]
this.setData({
names:newList
})
// 2 修改陣列
this.setData({
'names[1]':'justin'
})
// 3 刪除陣列
this.data.names.slice(1)
this.setData({
names:this.data.names.slice(1)
})
},
雙向資料繫結:input checkbox
<input type="text" model:value='{{name}}'/>
<checkbox model:checked="{{isCheck}}"/>
列表渲染
- 預設每個物件是item,預設每個下標是index
- wx:key 提升效能,不寫會警告 可以用 index或 *this:代指item本身 要唯一
<view wx:for="{{List}}" wx:key="*this">
{{item}}</text> -->
</view>
修改wx:for-index wx:for-item
<view wx:for="{{List}}" wx:key="*this" wx:for-item="info">
<text>{{info}}</text>
</view>
條件渲染 wx:if wx:elif wx:else
<view>
<input type="text" model:value='{{score}}' style="border:orange solid 1rpx"/>
<view wx:if="{{score>=90&&score<=100}}">優秀</view>
<view wx:elif="{{score>=80&&score<90}}">良好</view>
<view wx:elif="{{score>=60&&score<80}}">及格</view>
<view wx:else>不及格</view>
</view>
傳送網路請求
傳送網路請求的域名,必須在微信公眾平臺配置
handleLoadData(){
wx.showLoading({
title: '載入中,稍後',
mask:true // 顯示透明蒙層
})
wx.request({
url: 'http://192.168.71.100:5000',
method:'GET',
data:{},
header:{},
success:(res)=>{
wx.hideLoading()
console.log(res.data)
this.setData({
userinfo:res.data,
})
console.log(this.data.name)
},
fail:(err)=>{},
complete:(res)=>{}
})
},
loading提示框
# 顯示
wx.showLoading({
title: '載入中,稍後',
mask:true // 顯示透明蒙層
})
#關閉
wx.hideLoading()
對話方塊
模態對話方塊
##### wxml
<button type="default" size="mini" bind:tap="showModel">彈出模態框</button>
### js ###
showModel(){
wx.showModal({
title: '這是標題',
content: '這是內容部分~~',
complete: (res) => {
if (res.cancel) {
console.log('使用者取消了')
}
if (res.confirm) {
console.log('使用者確認了')
}
}
})
}
訊息對話方塊
#### wxml
<button type="default" size="mini" bind:tap="showToast">彈出訊息框</button>
### js
showToast(){
wx.showToast({
title: '恭喜您,秒殺成功',
icon:"success",
duration:2000
})
}
儲存
#### wxml####
<button type="default" plain bind:tap="handleSave">儲存資料</button>
<button type="primary" plain bind:tap="handleGet">獲取資料</button>
<button type="default" plain bind:tap="handleDelete">刪除資料</button>
<button type="primary" plain bind:tap="handleClear">清空資料</button>
###js### 同步####
handleSave() {
wx.setStorageSync('name', "justin")
wx.setStorageSync('userinfo', {name:'lqz',age:19})
},
handleGet() {
const name=wx.getStorageSync('name')
const userinfo=wx.getStorageSync('userinfo')
console.log(name)
console.log(userinfo)
},
handleDelete() {
wx.removeStorageSync('name')
},
handleClear() {
wx.clearStorageSync()
}
###js### 非同步####
handleSave() {
wx.setStorage({
key:'name',
data:"justin"
})
wx.setStorage({
key:'userinfo',
data:{name:'lqz',age:19}
})
},
async handleGet() {
const name= await wx.getStorage({key:'name'})
const userinfo= await wx.getStorage({key:'userinfo'})
console.log(name)
console.log(userinfo)
},
handleDelete() {
wx.removeStorage({key:'name'})
},
handleClear() {
wx.clearStorage()
}
上拉下拉載入
方式一
###### js####
// index.js
Page({
data: {
page: 1,
goods: []
},
refresh(page) {
wx.showLoading({
title: '載入中',
mask: true
})
wx.request({
url: 'http://127.0.0.1:8000/api/v1/course/actual/?page=' + page,
method: 'GET',
success: res => {
console.log(res.data.code == 100);
if (page == 1) {
this.setData({
goods: res.data.results
})
} else {
const resData = this.data.goods.concat(res.data.results)
this.setData({
goods: resData
})
}
},
complete: () => {
wx.hideLoading()
}
})
},
onLoad() {
this.refresh(this.data.page)
},
onReachBottom() {
this.data.page++
console.log('上拉了');
},
onPullDownRefresh() {
this.data.page = 1
this.refresh(this.data.page)
if (this.data.goods.length == 3) {
wx.stopPullDownRefresh()
}
}
})
####wxml#####
<view wx:for="{{goods}}" wx:key="index">{{item.name}}</view>
### wxss###
view{
height: 400rpx;
display: flex;
justify-content: center;
align-items: center;
}
/* 奇數 */
view:nth-child(odd){
background-color: pink;
}
/* 偶數 */
view:nth-child(even){
background-color: green;
}
#### json####
{
"usingComponents": {},
"onReachBottomDistance": 50,
"enablePullDownRefresh": true,
"backgroundColor": "#efefef",
"backgroundTextStyle":"dark"
}
方式二 scroll-view
##### wxml####
<scroll-view
class="scroll"
scroll-y
lower-threshold="100"
bindscrolltolower="handleGetData"
refresher-enabled="true"
refresher-default-style="black"
refresher-background="#f0f0f0"
bindrefresherrefresh="handleReload"
refresher-triggered="{{isRefresh}}"
enable-back-to-top="true"
>
<view wx:for="{{goods}}" wx:key="index">{{item.name}}</view>
</scroll-view>
### wxss####
.scroll{
/* 100vh就是指元素的高度等於當前瀏覽器的視窗高度,即瀏覽器內部的可視區域的高度大小 */
height: 100vh;
background-color: grey;
}
view{
height: 400rpx;
display: flex;
justify-content: center;
align-items: center;
}
/* 奇數 */
view:nth-child(odd){
background-color: pink;
}
/* 偶數 */
view:nth-child(even){
background-color: green;
}
### js#####
// pages/my/my.js
Page({
data: {
page: 0,
goods: [],
isRefresh: false
},
refresh(page) {
wx.showLoading({
title: '載入中',
mask: true
})
wx.request({
url: 'http://127.0.0.1:8000/api/v1/course/actual/?page=' + page,
method: 'GET',
success: res => {
if (page == 1) {
this.setData({
goods: res.data.results
})
} else {
const resData = this.data.goods.concat(res.data.results)
this.setData({
goods: resData
})
}
},
complete: () => {
wx.hideLoading()
}
})
},
handleGetData() {
this.data.page++
console.log('上拉了')
this.refresh(this.data.page)
},
handleReload() {
console.log('下拉重新整理了')
wx.showToast({
title: '下拉重新整理',
})
this.data.page = 1
this.refresh(this.data.page)
this.setData({
isRefresh: false
})
}
})
更新
強制更新
- 訪問小程式,微信會將小程式程式碼包,下載到微信本地,開啟使用
- 當小程式更新版本後,微信會檢查小程式版本有沒有更新,並下載最新小程式
- 更新方式:啟動時同步更新,啟動時非同步更新
### 同步更新####
啟動時同步更新:微信執行時,會定期檢查最近使用的小程式是否有更新。如果有更新,下次小程式啟動時會同步進行更新,更新到最新版本後再開啟小程式。如果 使用者長時間未使用小程式時,會強制同步檢查版本更新
-如果更新失敗,還是會使用本地版本
-新版本釋出24小時後,基本會覆蓋全部使用者
### 非同步更新####
啟動時非同步更新:在啟動前沒有發現更新,小程式每次 冷啟動 時,都會非同步檢查是否有更新版本。如果發現有新版本,將會非同步下載新版本的程式碼包,將新版本的小程式在下一次冷啟動進行使用,當前訪問使用的依然是本地的舊版本程式碼
## 強制更新###
在啟動時非同步更新的情況下,如果開發者希望立刻進行版本更新,可以使用 wx.getUpdateManager API 進行處理。在有新版本時提示使用者重啟小程式更新新版本
在app.js中加入
App({
// 生命週期函式,啟動小程式就會執行
onLaunch(){
const update=wx.getUpdateManager()
update.onUpdateReady(function(){
wx.showModal({
title: '發現新版本',
content: '重啟應用,更新版本新版本?',
success:(res)=>{
if(res.confirm){
update.applyUpdate()
}
}
})
})
}
})
生命週期
應用生命週期
// app.js
App({
/**
* 當小程式初始化完成時,會觸發 onLaunch(全域性只觸發一次)
*/
onLaunch: function () {
console.log('小程式啟動了')
},
/**
* 當小程式啟動,或從後臺進入前臺顯示,會觸發 onShow
*/
onShow: function (options) {
console.log('後臺切前臺了')
},
/**
* 當小程式從前臺進入後臺,會觸發 onHide
*/
onHide: function () {
console.log('進後臺了')
},
})
頁面生命週期
Page({
/**
* 生命週期函式--監聽頁面載入
*/
onLoad(options) {
console.log('1 頁面載入了')
},
/**
* 生命週期函式--監聽頁面初次渲染完成
*/
onReady() {
console.log('3 初次渲染完成')
},
/**
* 生命週期函式--監聽頁面顯示
*/
onShow() {
console.log('2 頁面顯示')
},
/**
* 生命週期函式--監聽頁面隱藏
*/
onHide() {
console.log('4 頁面隱藏')
},
/**
* 生命週期函式--監聽頁面解除安裝
*/
onUnload() {
console.log('5 頁面解除安裝')
},
})
轉發給朋友
方式一:透過右上方 ...
Page({
onShareAppMessage() {
return {
title:"是朋友就點一下",
query: 'name=justin&age=19',
imageUrl:'/images/b.jpg'
}
},
})
方式二:透過按鈕, 需要給button設定 open-type="share"
####wxml####
<button open-type="share">轉發</button>
####js####
onShareAppMessage() {
return {
title:"是朋友就點一下",
path:"/pages/my/my", //當前轉發的頁面
imageUrl:'/images/b.jpg'
}
},
分享到朋友圈
- 必須有分享給朋友
onShareTimeline(){
return {
title:"這是一個神奇的頁面",
query:'name=justin&age=19',
imageUrl:'/images/b.jpg'
}
},
獲取頭像
#### js###
Page({
data:{
phono: '/static/img/b.jpg'
},
choosePhoto(event){
console.log(event.detail.avatarUrl)
this.setData({
phono:event.detail.avatarUrl
})
}
})
#####wxml###
<button class="btn" open-type="chooseAvatar" bindchooseavatar="choosePhoto">
<image src="{{phono}}" class="photo"/>
</button>
###wxss###
.btn{
/* 透明的 */
background-color: transparent;
}
/* 去掉邊框 */
.btn::after{
border: none;
}
.photo{
height: 250rpx;
width: 250rpx;
border-radius: 50%;
}
獲取暱稱
### wxml###
<input type="nickname" placeholder="輸入或獲取暱稱" model:value="{{username}}"/>
<button type="primary" plain bind:tap="showName">提交</button>
###js####
Page({
data:{
username:"",
},
showName(){
console.log(this.data.username)
}
})
###wxss##
input {
border: 1rpx solid pink;
border-radius: 10rpx;
padding: 10rpx;
margin: 10rpx;
}
手機號快速驗證
# 步驟1:需要將 button 元件 open-type 的值設定為 getPhoneNumber,當使用者點選並同意之後,透過 bindgetphonenumber 事件獲取回撥資訊;
# 步驟2:將 bindgetphonenumber 事件回撥中的動態令牌code傳到開發者後臺,並在開發者後臺呼叫微信後臺提供的 phonenumber.getPhoneNumber 介面,消費code來換取使用者手機號。每個code有效期為5分鐘,且只能消費一次。
# 步驟3:後端拿到code --》呼叫getuserphonenumber 換取手機號
https://developers.weixin.qq.com/miniprogram/dev/OpenApiDoc/user-info/phone-number/getPhoneNumber.html
# 步驟4:去咱們自己使用者表中查
-能查到---之前用過,註冊了--》簽發token
-查不到--》第一次用--執行註冊--》簽發token
手機號實時驗證
# 步驟1:需要將 button 元件 open-type 的值設定為 getRealtimePhoneNumber,當使用者點選並同意之後,透過 bindgetrealtimephonenumber 事件獲取回撥資訊;
# 步驟2:將 bindgetrealtimephonenumber 事件回撥中的動態令牌code傳到開發者後臺,並在開發者後臺呼叫微信後臺提供的 phonenumber.getPhoneNumber 介面,消費code來換取使用者手機號。每個code有效期為5分鐘,且只能消費一次
###wxml###
<button type="warn" open-type="getPhoneNumber"
bindgetphonenumber="getPhoneNumber">快速手機號</button>
<button type="default" plain open-type="getRealtimePhoneNumber"
bindgetrealtimephonenumber="getRealPhoneNumber"
>快速手機號</button>
###js###
getPhoneNumber(event) {
console.log(event)
// 透過獲取手機號返回的code--傳遞給後端--後端呼叫:POST https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token=ACCESS_TOKEN -->獲取手機號--》後端簽發token給前端
雲呼叫
wx.request({
url: '我們後端地址',
method:'POST',
data:{
code:event.detail.code
},
success:(res)=>{
//在此返回登入資訊,使用者登入
}
})
},
getRealPhoneNumber(event) {
console.log(event)
}
客服功能
微信為小程式提供客服訊息能力,以便小程式使用者可以方便快捷地與小程式服務提供方進行溝通
https://developers.weixin.qq.com/miniprogram/introduction/custom.html
## wxml##
<button type="default" plain open-type="contact">聯絡客服</button>
vant-app
https://vant-ui.github.io/vant-weapp/#/home
使用npm包
- 專案根目錄,開啟終端【在內建終端開啟】
npm init -y # 會生成package.json檔案
- 安裝vant
npm i @vant/weapp -S
# package.json 能看到下載完成,專案目錄下有node_modules
#(可以使用cnpm:npm install -g cnpm --registry=https://registry.npm.taobao.org)
-
將 app.json 中的 "style": "v2" 去除,小程式的新版基礎元件強行加上了許多樣式,難以覆蓋,不關閉將造成部分元件樣式混亂
-
project.config.json 的settings中加入
"packNpmManually": true,
"packNpmRelationList": [
{
"packageJsonPath": "./package.json",
"miniprogramNpmDistDir": "./"
}
]
- 構建 工具---》構建npm