2019.12.16號(hào)開始接觸小程序虐先,也是第一次接觸暮蹂。隨筆寫些流程也好寞缝,想法也罷,方便之后參考仰泻。
一荆陆、小程序簡(jiǎn)介
1.小程序是一種全新的連接用戶與服務(wù)的方式。
2.小程序并非憑空冒出來的一個(gè)概念集侯,當(dāng)微信中的WebView逐漸成為移動(dòng)Web的一個(gè)重要入口時(shí)被啼,微信就有相關(guān)的JS API了。
3.小程序的主要語言是JavaScript棠枉。小程序的邏輯層和渲染層是分開的浓体,邏輯層運(yùn)行在JSCore中,并沒有一個(gè)完整瀏覽器對(duì)象辈讶,因而缺少相關(guān)的DOM API和BOM API命浴。這一區(qū)別導(dǎo)致了前端開發(fā)非常熟悉的一些庫,例如jQuery等贱除,在小程序中是無法運(yùn)行的生闲。同時(shí)JSCore的環(huán)境同NodeJS環(huán)境也不盡相同,所以一些NPM的包在小程序中也是無法運(yùn)行的(只是一部分不可使用勘伺,小程序還是支持npm的)
4.小程序的開發(fā)需要經(jīng)過:申請(qǐng)小程序賬號(hào)跪腹、安裝小程序開發(fā)者工具、配置項(xiàng)目等等過程方可完成飞醉。下面是小程序申請(qǐng)賬號(hào)的官方文檔冲茸,一步步的按步驟進(jìn)行即可屯阀。
https://developers.weixin.qq.com/miniprogram/dev/framework/quickstart/getstart.html
二、小程序的代碼構(gòu)成
1.文件類型:
<1> .json后綴的JSON配置文件
<2> .wxml后綴的WXML配置文件
<3> .wxss后綴的WXSS配置文件
<4> .js后綴的JS配置文件
JSON配置:JSON是一種數(shù)據(jù)格式轴术,并非編程語言
2.創(chuàng)建頁面:
先在項(xiàng)目中創(chuàng)建一個(gè)文件夾难衰,然后在開發(fā)者工具中右鍵文件夾,點(diǎn)擊“新建Page”逗栽,起好名字后盖袭,會(huì)自動(dòng)創(chuàng)建“xx.js”、“xx.json”彼宠、“xx.wxml”鳄虱、“xx.wxss”四個(gè)文件。創(chuàng)建之后凭峡,會(huì)在項(xiàng)目app.json中的“pages”項(xiàng)中自動(dòng)生成路徑拙已。
3.app.json配置介紹
<1>pages:各個(gè)頁面的路徑,可以理解在這里配置路由摧冀。
<2>permission:在小程序開發(fā)中倍踪,需要獲取用戶所在地理位置,需要在app.json中增加premission屬性配置索昂。
"permission": {
"scope.userLocation": {
"desc": "你的位置信息將用于小程序位置接口的效果展示"
}
}
<3>window:
用于設(shè)置小程序的狀態(tài)欄建车、導(dǎo)航條、標(biāo)題椒惨、窗口背景色缤至。
每一個(gè)小程序頁面都可以使用.json文件對(duì)本頁面的窗口表現(xiàn)進(jìn)行配置(可以理解成小程序頁面的頂部靠.json中的window來設(shè)置,不過也是可以自定義的框产,用window方便一些)凄杯。
頁面中配置項(xiàng)在當(dāng)前頁面會(huì)覆蓋app.json的window中相同的配置項(xiàng)(可以理解每個(gè)頁面中的json配置項(xiàng)的優(yōu)先級(jí)大于app.json配置項(xiàng))。
<4>usingComponents:
引入組件
這真是我最想吐槽的一個(gè)點(diǎn)秉宿。戒突。真xxx的是xxx的難用!描睦!
感受一下:我用小程序的組件膊存,不能全局引用,用到哪個(gè)引入哪個(gè)忱叭,最恐怖的是路徑還要自己去文件夾中找隔崎。
目前我是這樣用的,如果有更好的用法韵丑,希望有大佬指點(diǎn)一下爵卒!
"usingComponents": {
"l-loading": "/miniprogram_npm/lin-ui/loading/index",
"l-tabs": "/miniprogram_npm/lin-ui/tabs/index",
"l-tabpanel": "/miniprogram_npm/lin-ui/tabpanel/index",
"l-input": "/miniprogram_npm/lin-ui/input/index",
"l-textarea": "/miniprogram_npm/lin-ui/textarea/index",
"l-search-bar": "/miniprogram_npm/lin-ui/search-bar/index"
},
<5>tabBar:
如果小程序是一個(gè)多tab應(yīng)用(客戶端窗口的底部或頂部有tab欄可以切換頁面),可以通過tabBar配置項(xiàng)指定tab欄的表現(xiàn)撵彻,以及tab切換時(shí)顯示的對(duì)應(yīng)頁面钓株。
小程序的這一點(diǎn)我覺得還是很好用的实牡,用vue來說就是一個(gè)底部標(biāo)簽頁的組件,我用vue要用狀態(tài)管理要自己封裝引入轴合,然后在小程序自己定義一個(gè)tabBar就可以搞定了创坞。
"tabBar": {
"color": "#8c8c8c",
"selectedColor": "#2A5AAA",
"backgroundColor": "#fff",
"list": [
{
"pagePath": "pages/index/index",
"text": "首頁",
"selectedIconPath": "./images/assets/我的訂單(選中狀態(tài))@3x.png",
"iconPath": "./images/assets/我的訂單(未選中)@3x.png"
},
{
"pagePath": "pages/logs/logs",
"text": "設(shè)置",
"selectedIconPath": "./images/assets/設(shè)置(選中)@3x.png",
"iconPath": "./images/assets/設(shè)置(未選中)@3x.png"
}
],
"position": "bottom"
},
4.項(xiàng)目思路
1.app.js:用戶每次登錄都會(huì)調(diào)用wx.login接口獲取code,并將code存入緩存受葛。判斷用戶是否之前已經(jīng)授權(quán)信息题涨,如果已授權(quán)則直接進(jìn)入index首頁,仍未授權(quán)進(jìn)入login登錄頁总滩。
2.login.js:登陸頁面纲堵。用戶點(diǎn)擊登錄按鈕,彈出授權(quán)框咳秉,點(diǎn)擊授權(quán)進(jìn)入手機(jī)綁定頁面婉支,拒絕授權(quán)則停留在當(dāng)前頁面。
3.information:手機(jī)綁定頁面澜建。用戶第一次授權(quán)成功后進(jìn)入手機(jī)綁定頁面。綁定成功后進(jìn)入首頁蝌以。
4.index:首頁炕舵。在首頁點(diǎn)擊任意一條信息進(jìn)入信息詳情頁。并且將本條信息的單號(hào)和tabNum傳給信息詳情頁跟畅。
5.orderDetails:信息詳情頁咽筋。接受上一頁的單號(hào)和tabNum傳給回單上傳頁面。
6.replyUpload:回單上傳頁徊件。點(diǎn)擊添加圖片調(diào)用wx.chooseImage選擇圖片后調(diào)用后臺(tái)接口奸攻,將已選擇圖片信息上傳給服務(wù)器,并且獲取返回值id虱痕。點(diǎn)擊確定上傳對(duì)接上傳接口睹耐,將id作為參數(shù)上傳。上傳成功后返回index首頁部翘。
eg:用戶再次進(jìn)入該項(xiàng)目的時(shí)候硝训,繼續(xù)執(zhí)行第一步,不過已經(jīng)授權(quán)過新思,則會(huì)直接進(jìn)入index首頁窖梁,以上是此項(xiàng)目的一個(gè)大概的思路流程。
三夹囚、小程序應(yīng)用點(diǎn)
1.小程序本地存儲(chǔ)
//存數(shù)據(jù)
wx.setStorageSync("code",res.code);
//取數(shù)據(jù)
wx.getStorageSync("code")
2.存數(shù)據(jù)到當(dāng)前頁面data中
//控制顯隱時(shí)立刻生效
that.setData({
list: res.data.list
});
//單純的賦值
that.data.list = res.data.list
其實(shí)這里面原本是this.setData纵刘,而至于為什么要用that,是因?yàn)椋?br> 如果使用this在函數(shù)中的話會(huì)出現(xiàn)——使用回調(diào)函數(shù)異常
報(bào)錯(cuò)信息:TypeError: Cannot read property 'setData' of undefined
問題:作用域問題荸哟,回調(diào)函數(shù)中的作用域已經(jīng)脫離了調(diào)用函數(shù)假哎,因此需要在回調(diào)函數(shù)外邊把this賦給一個(gè)新的變量
才可以
解決方法:var that = this;
建議:****在每一個(gè)方法中都先定義一下that瞬捕,每次都使用that****
3.小程序傳參/接參
路由傳參
很重要的一點(diǎn):url里面都是字符串
傳參如果是對(duì)象類型或者數(shù)組,隱式轉(zhuǎn)換為[Object,Object]
JSON.stringify():JavaScript => JSON (直接轉(zhuǎn))
JSON.parse():JSON => JavaScript(先轉(zhuǎn)為 JSON 再轉(zhuǎn)為 JS)
wx.navigateTo({
url:
"/pages/****/****?orderMovementGid=" +
orderMovementGid +
"&tabNum=" +
that.data.tabNum
});
onLoad: function(options) {
var that = this;
that.setData({
orderMovementGid: options.orderMovementGid,
tabNum: options.tabNum
});
}
小程序傳參
wx.navigateTo({
url: "/pages/costFallIn/costFallIn",
success: function (res) {
// 通過eventChannel向被打開頁面?zhèn)魉蛿?shù)據(jù)
res.eventChannel.emit("acceptDataFromOpenerPage", {
status: "chaKan",
id,(前后一樣可以寫一個(gè)就ok了)
tlFiles: item.tlFiles,
});
},
});
const eventChannel = this.getOpenerEventChannel()
// 監(jiān)聽acceptDataFromOpenerPage事件位谋,獲取上一頁面通過eventChannel傳送到當(dāng)前頁面的數(shù)據(jù)
eventChannel.on('acceptDataFromOpenerPage', function(data) {
console.log(data)
})
4.頁面跳轉(zhuǎn)
頁面跳轉(zhuǎn)的話還是參考一下官方文檔山析,有好幾種跳轉(zhuǎn)
我最常用的幾種:wx.switchTab(需要跳轉(zhuǎn)至tab頁)蜘澜,wx.redirectTo(需要跳轉(zhuǎn)至非tab頁)懂版,wx.navigateTo(跳轉(zhuǎn)至下一頁,自帶返回按鈕)
https://developers.weixin.qq.com/miniprogram/dev/api/route/wx.switchTab.html
5.onLoad和onShow
不需要刷新的函數(shù)寫在onLoad里面,
需要刷新的函數(shù)寫在onShow里面家浇。
(這里onShow可以理解為監(jiān)控路由赊淑,路由發(fā)生變化的時(shí)候爵政,重新調(diào)用onShow)
6.開發(fā)者工具
<1>預(yù)覽:使用開發(fā)者工具預(yù)覽小程序,點(diǎn)擊“預(yù)覽”按鈕陶缺,開發(fā)者工具會(huì)自動(dòng)打包當(dāng)前項(xiàng)目钾挟,并上傳小程序代碼至微信的服務(wù)器。
<2>上傳:點(diǎn)擊上傳的話饱岸,相當(dāng)于打包當(dāng)前小程序掺出,發(fā)送“體驗(yàn)版”,可以在微信后臺(tái)管理中進(jìn)行查看苫费。
<3>開發(fā)者工具不能識(shí)別1rpx汤锨,最低2rpx(1px)
手機(jī)可以識(shí)別1rpx
7.小程序解決文字超出不換行問題
display:block;
word-break: break-all;
word-wrap: break-word;
//彈性布局換行
flex-wrap: wrap;
8.點(diǎn)擊事件(bindtap="xxx")
.wxml
<view class="bottomButton" bindtap="okBinding">確認(rèn)綁定</view>
.js
okBinding: function() {}
點(diǎn)擊事件傳參,不能有()會(huì)報(bào)警告
需要給元素綁定 data-id='{{item.id}}'百框。
從事件對(duì)象中:e.currentTarget.dataset.id獲取闲礼。
(多個(gè)參數(shù)就綁定多個(gè)data-xxx='{{item.xxx}}')
9.獲取input輸入框內(nèi)容(bindInput="xxx")
.wxml
<input label="手機(jī)號(hào)" placeholder="請(qǐng)輸入手機(jī)號(hào)" type="number" bindinput="phoneInput"/>
.js
//每次輸入都會(huì)觸發(fā)這個(gè)事件
phoneInput: function(e) {
this.data.phoneNum = e.detail.value;
},
10.控制顯隱(wx:if)
<view wx:if="{{tabNum=='PICKUP'}}" >確認(rèn)提貨</view>
11.循環(huán)遍歷(wx:for)
<view class="midContent" wx:for="{{list}}" wx:key="{{index}}"></view>
wx:for-item="item1" wx:for-index="index1"
12.設(shè)置頂部標(biāo)題
"navigationBarTitleText": "首頁"
動(dòng)態(tài)更改小程序頂部標(biāo)題
wx.setNavigationBarTitle({
title: "我是修改后的標(biāo)題"
});
自定義頂部導(dǎo)航欄
"navigationStyle": "custom",
13.回調(diào)函數(shù)——我覺得很不友好的一點(diǎn)
比如我們一個(gè)回調(diào)函數(shù),正確的話進(jìn)入success铐维,錯(cuò)誤的話進(jìn)入fail柬泽。
但是小程序的回調(diào)函數(shù)不同,這是官方解釋
只要成功接收到服務(wù)器返回嫁蛇,無論statusCode是多少锨并,都會(huì)進(jìn)入success回調(diào)。請(qǐng)開發(fā)者根據(jù)業(yè)務(wù)邏輯對(duì)返回值進(jìn)行判斷棠众。
也就是說我們即使調(diào)通接口失敗了琳疏,只要后臺(tái)返回給我們信息了,也要通過statusCode來判斷闸拿。
四空盼、封裝組件(自定義提示框)
<1>新建文件夾
在根目錄下新建components文件夾,然后在文件夾中新建自定義目錄新荤,再右鍵“新建Page”揽趾,(記得把prompt-box.js中表頭的Page改成Component)。
<2>組件:json配置
{
"component":true //官方文檔說的是:將component字段設(shè)為true可將這一組文件設(shè)為自定義組件
}
<3>組件:wxml編寫
<!-- 提示框組件 -->
<view class="promptBox">
提示框
</view>
<4>app.json全局引入組件
"usingComponents": {
"prompt-box": "./components/prompt-box/prompt-box"
}
<5>父組件:使用組件
<prompt-box></prompt-box>
五苛骨、父子傳值
1.子文件→父文件篱瞎。(通過 triggerEvent 事件)(需要手動(dòng)觸發(fā)獲裙赌拧)
.wxml
<!-- 提示框組件 -->
<view class="promptBox">
<view class="buttonBox" bindtap="toUpperLevel">朕知道了</view>
</view>
.js
// 點(diǎn)擊“朕知道了”,傳遞給父組件信息
toUpperLevel: function(e) {
this.triggerEvent("clickzdl", "zzdl");
},
//通過bind:clickzdl="clickzdlClick"把子組件的clickzdl事件綁定在父組件的clickzdlClick事件上
.wxml
<prompt-box bind:clickzdl="clickzdlClick"></prompt-box>
.js
// 點(diǎn)擊“朕知道了”俐筋,接受子組件信息
clickzdlClick: function(e) {
var that = this;
console.log("子組件給父組件傳值");
console.log(e);
if (e.detail == "zzdl") {
that.setData({
promptBoxShow: false
});
}
},
2.父組件→子組件牵素。
.wxml (要傳給子組件的數(shù)據(jù))
<prompt-box propA="{{dataFieldA}}"></prompt-box>
.js
Page({
data: {
dataFieldA: "登陸異常,請(qǐng)聯(lián)系管理員"
},
.js
Component({
data: {
errMsg: "程序出現(xiàn)錯(cuò)誤澄者,請(qǐng)聯(lián)系管理員"
},
properties: {
propA: {
type: String
}
},
lifetimes: {
attached: function() {
var that = this;
// console.log(that.properties);
that.setData({
errMsg: that.properties.propA
});
}
}
});
六笆呆、驗(yàn)證碼倒計(jì)時(shí)(定時(shí)器)
.wxml
<button class="QRcode">
<text bindtap="gainCode" wx:if="{{codeShow}}">獲取驗(yàn)證碼</text>
<text wx:if="{{!codeShow}}">{{timeDown}}s</text>
</button>
.js
var that = this;
let time = setInterval(function() {
that.setData({
codeShow: false,
timeDown: that.data.timeDown - 1
});
if (that.timeDown == 0) {
that.setData({
codeShow: true,
timeDown:60
});
clearInterval(time);
console.log("清除");
}
}, 1000);
七、下拉刷新粱挡,上拉加載
官方文檔:https://developers.weixin.qq.com/miniprogram/dev/reference/api/Page.html#onPullDownRefresh
app.json
{
"usingComponents": {},
"navigationBarTitleText": "我的訂單",
"enablePullDownRefresh": true, //設(shè)置為true則默認(rèn)開啟下拉刷新功能
"onReachBottomDistance": 10 //上拉加載的觸發(fā)距離
}
1.下拉刷新
onPullDownRefresh監(jiān)聽用戶下拉刷新事件
onPullDownRefresh: function() {
wx.showNavigationBarLoading(); //在標(biāo)題欄中顯示加載(小菊花)
//模擬加載 模擬網(wǎng)絡(luò)加載所消耗的時(shí)間
setTimeout(function() {
wx.hideNavigationBarLoading(); //在標(biāo)題欄中隱藏加載(小菊花)
wx.stopPullDownRefresh(); //停止下拉刷新
}, 1500);
},
2.上拉加載更多數(shù)據(jù)
onReachBottom監(jiān)聽用戶上拉觸底事件
在json文件中設(shè)置觸發(fā)onReachBottom的觸發(fā)距離onReachBottomDistance
在觸發(fā)距離內(nèi)滑動(dòng)期間赠幕,本事件只會(huì)被觸發(fā)一次
onReachBottom: function() {
console.log("加載更多");
let listConcat = [...that.data.list, ...res.data.data.content];
that.setData({
list: listConcat
});
},
八、很重要的一點(diǎn)
在微信小程序中询筏,盒子模型box-sizing屬性默認(rèn)是content-box
可以在每個(gè)標(biāo)簽后加上
box-sizing: border-box;
或者app.wxss加上 小程序所有組件初始化樣式 box-sizing: border-box
view,scroll-view,swiper,swiper-item,movable-area,movable-view,cover-view,cover-image,icon,text,rich-text,progress,button,checkbox-group,checkbox,form,input,label,picker,picker-view,radio-group,radio,slider,switch,textarea,navigator,functional-page-navigator,image,video,camera,live-player,live-pusher,map,canvas,open-data,web-view,ad{
box-sizing: border-box;
}
九榕堰、小程序的棧!
首先嫌套,先明確兩點(diǎn)
1.小程序的onLoad方法在頁面的生命周期中逆屡,只執(zhí)行一次。
2.先執(zhí)行onLoad踱讨,后執(zhí)行onShow康二。
前提:用戶——>首頁(A頁面)——>上傳頁面(B頁面)。棧的示意圖
第一種情況:進(jìn)入上傳頁面(B頁面)之后勇蝙,使用redirectTo返回首頁(C頁面)。redirectTo會(huì)將棧頂出棧挨约,新頁面入棧味混,即B頁面出棧,C頁面進(jìn)棧诫惭。(redirectTo會(huì)進(jìn)行頂部棧的替換)
第二種情況:進(jìn)入上傳頁面(B頁面)之后翁锡,使用navigateTo返回首頁(C頁面)。navigateTo會(huì)將C頁面添加到棧頂夕土。
第三種情況:即不使用redirectTo馆衔,也不使用navigateTo,使用navigateBack返回至首頁怨绣。在A頁面onShow中打印棧的信息角溃,只有miniHome(A頁面)。
實(shí)例參考:https://www.cnblogs.com/caicaizi/p/6652103.html
var pagelist = getCurrentPages();
var currPage = pagelist[pagelist.length - 1]; //當(dāng)前頁面
var prevPage = pagelist[pagelist.length - 2]; //上一個(gè)頁面
prevPage.setData({
statusOk: "直接給上一個(gè)頁面中的字段賦值",
});
wx.navigateBack({
delta: 1,
});
上一個(gè)頁面在onShow中進(jìn)行操作篮撑,因?yàn)轫撁娓淖兗跸福梢杂|發(fā)onShow
跳轉(zhuǎn)頁面?zhèn)鲄⒌脑捲趏nLoad
十、微信小程序圖片顯示問題(IOS訪問正常赢笨,安卓訪問不顯示)
有以下幾種可能:
1.非本地圖片:確定圖片資源存在未蝌,copy圖片url在瀏覽器打開驮吱,確定圖片資源存在且能正常訪問。
2.本地圖片:確定相對(duì)路徑或者絕對(duì)路徑正確萧吠。
3.微信小程序圖片路徑左冬,不可存在中文,使用英文做路徑和文件名纸型。
4.文件后綴文小寫且保持正確拇砰。
5.網(wǎng)絡(luò)圖片,必須確保域名已經(jīng)備案绊袋。
注:排除以上5種通病之后毕匀,仍出現(xiàn)IOS訪問正常,安卓訪問不到圖片的問題癌别,大概率原因是圖片做了CDN轉(zhuǎn)發(fā)皂岔,多數(shù)CDN會(huì)默認(rèn)開啟防盜鏈,需要關(guān)閉CDN防盜鏈展姐,因?yàn)榉辣I鏈會(huì)導(dǎo)致瀏覽器能顯示躁垛,而客戶端無法顯示。
本內(nèi)容轉(zhuǎn)自:https://www.cnblogs.com/sheep-sheep/p/9645797.html
十一圾笨、Loading
wx.showLoading({
icon: "loading",
title: "Loading",
mask: true,
})教馆;
wx.hideLoading();
wx.showToast({
title: "刷新成功",
icon: "success",
duration: 1000,
});
下拉刷新時(shí)
wx.showNavigationBarLoading(); //在標(biāo)題欄中顯示加載(小菊花)
wx.hideNavigationBarLoading(); //在標(biāo)題欄中隱藏加載(小菊花)
wx.stopPullDownRefresh(); //停止下拉刷新
十二、forEach
1.邏輯盡量寫在JS文件中
2.多個(gè)三步運(yùn)算符擂达,要加()
3.forEach循環(huán)中土铺,element相當(dāng)于item,可以直接點(diǎn)點(diǎn)使用板鬓,
一個(gè)參數(shù)可以直接寫悲敷,多個(gè)參數(shù)要加()
that.data.list.forEach((element, index) => {
if (element.stopStatus == "ARRIVED") {
that.setData({
statusList: [index],
changeIndex: index,
});
}
});
十三、接口
小程序可以調(diào)用本地接口
1.拉下來后臺(tái)代碼俭令,在前端的電腦上跑起來后德,然后localhost調(diào)接口。
2.后臺(tái)自己跑起來服務(wù)抄腔,用后臺(tái)的ip地址調(diào)用接口瓢湃。
十四、報(bào)文
請(qǐng)求報(bào)文:前端給后臺(tái)傳參赫蛇。
響應(yīng)報(bào)文:后臺(tái)給前端的返回值绵患。
十五、關(guān)于canvas
1.滑動(dòng)問題
前提:設(shè)置canvas寬度大于當(dāng)前可視屏幕寬度棍掐,但是卻無法左右滑動(dòng)藏雏。
問題:設(shè)置class mask遮罩物,z-index 99 在開發(fā)者工具上可以正常滑動(dòng)掘殴,但是在真機(jī)上無法滑動(dòng)赚瘦。
原因:(1)canvas是原生組件,原生組件層級(jí)最高奏寨,其他組件無法通過z-index來覆蓋原生組件起意。
(2)原生組件脫離WebView渲染流程。但是在開發(fā)者工具上病瞳,原生組件是用web組件模擬的揽咕,不能完全還原真機(jī)效果。
解決方法:使用cover-view
和cover-image
可以覆蓋部分原生組件上面套菜。(這兩個(gè)是小程序提供的原生組件亲善,專門用來解決原生組件層級(jí)問題的)
原生組件的使用限制:https://developers.weixin.qq.com/miniprogram/dev/component/native-component.html