關於服務器域名的配置
小程序中wx.request請求的接口,必須要在後臺開發設置中配置對應的域名,如果api有端口,則配置域名時必須帶上端口。值得注意的是,微信一個月內只允許申請修改5次,由於後臺提供的接口端口號比較多,剛開始沒有意識到這個問題,導致後面無法配置剩餘的域名端口進而無法訪問,這是一個很蛋疼的問題,最終在和後端同事的討論下,借用已配置的域名做了一箇中轉,也就是我去訪問已配置的域名,傳要請求的api和參數及請求方式給他,他那邊去幫我做請求然後將結果返回我,目前只能這樣處理了,等後面再改回來吧,希望看到的朋友注意一下。
關於業務域名的配置
小程序不存在iframe和localtion.hred的概念,所以要想跳轉外鏈,需藉助web-view標籤,web-view所跳轉的鏈接必須在後臺進行業務域名的配置,配置時注意以下幾點:1.域名需經過備案 2.域名可校驗,也就是說必須是自己的網站或者說是自己可以控制操作的網站 3.域名中不能含有端口號 4.注意修改次數,一年只可修改50次,最多可配置20個
在這個過程當中,同樣遇到過一個很蛋疼的問題,首先我的h5頁面是公用的,既想在app裏也可在小程序裏,爲了和ios那邊交互,我的h5頁面引用了一個必須的js文件,而這個js文件裏又加載了另外一個域名,web-view打開時默認也會去加載這個域名,而這個域名呢並不是我的,我也無法控制,所以就沒法進行校驗從而不能再後臺業務域名裏進行配置,從而被微信識別爲非法域名不能正常進行訪問。最開始採用的解決方案是單獨再寫一個不引用交互js的頁面,但考慮到後期公用的頁面比較多,也不可能一個一個去重寫,也不是我想要的結果,於是就從交互js上入手,在js裏域名那塊做了判斷,判斷是否在微信裏打開,如果是則不訪問該域名,因爲小程序裏不存在和ios的交互,所以也就不存在影響的問題。
點擊事件和參數傳遞
小程序的點擊事件不同於vue的@click和原生js的onclick而是用的bindtap='alert',alert爲方法名
如果需要傳遞參數,則需要在點擊元素上進行參數的定義,如data-obj='123',obj爲自定義 123爲值
方法裏面接受參數:
alert(e){
let obj = e.currentTarget.dataset.obj; // view接參格式
let obj = e.target.dataset.obj; // text接參格式
}
路由跳轉及傳參
最常用的莫過於wx.navigateTo,參數傳遞採用url拼接參數的形式,如果需要傳遞對象,可將對象轉化爲json字符串形式
wx.navigateTo({
url: '../home/home?id=123'
})
被跳轉頁面接參,可在監聽頁面加載生命週期中進行
onLoad: function (options) {
this.setData({
id: options.id,
})
},
需要注意的是,從普通頁面跳轉到tabBar頁面,需要用wx.switchTab
但目前switchTab不支持url傳參,如果想要傳遞參數,可考慮使用定義全局變量的方式
background-image不顯示
小程序用background-image設置背景圖片,在開發工具裏面看可以顯示,但在真機上無法顯示,查閱後才知道,背景圖片目前不支持加載本地資源,需加載網絡資源,可以考慮將圖片放到遠程服務器上面去。
onLoad和onShow的區別
onLoad 監聽頁面加載,頁面第一次加載是會觸發,可以把一些不需要實時更新的數據放入。
onShow 監聽頁面顯示,頁面加載就觸發,建議少放置操作減少請求。
之所以會關注這個問題 是在做登錄那塊的功能是 需要在storage裏面存儲一個參數 完了在首頁裏獲取 但發現在首頁裏默認習慣性在onLoad裏面去拿並不能及時獲取到 需要刷新重新加載之後纔可以 排除了異步加載的可能性之後 最終在onShow裏去獲取發現確實可以及時拿到 因爲onShow監聽的是頁面顯示 只要加載就會觸發
如何實現列表上拉加載和下拉刷新
最開始用的是小程序的視圖容器scroll-view去做,給定容器高度(如果是滿屏的話可以用wx.getSystemInfo獲取屏幕高度),然後用bindscrolltoupper和bindscrolltolower監聽滾動到頂部和底部,從而實現下拉刷新和上拉加載的目的。但配置和邏輯相對比較麻煩,有多個需要注意的點。
後來發現了一個更好的方法,就是page頁面本身提供的onPullDownRefresh和onReachBottom函數,直接監聽用戶是否有下拉刷新和上拉加載的動作,配置方便,邏輯判斷簡單。但缺點是,只能監聽整個頁面的動作,不能監聽頁面內的某一個容器的滾動事件,這一項不如scroll-view那樣靈活。
// 頁面下拉 歸爲首頁 下拉刷新
onPullDownRefresh: function () {
// 顯示導航欄loading
wx.showNavigationBarLoading();
// 調用接口加載數據
this.setData({
pageIndex: 1,
list: [],
isEnd: false,
})
this.getList();
// 隱藏導航欄loading
wx.hideNavigationBarLoading();
// 當處理完數據刷新後,wx.stopPullDownRefresh可以停止當前頁面的下拉刷新
wx.stopPullDownRefresh();
},
// 頁面上拉 向上滑 類似於向下翻頁
onReachBottom: function () {
if (!this.data.isEnd) {
this.setData({
pageIndex: this.data.pageIndex + 1
})
this.getList()
}
},
需要注意的是,使用時需要在json裏配置導航欄的樣式,否則下拉加載三個點效果看不是很清楚
{
"usingComponents": {},
"navigationBarTitleText": "我的訂單",
"enablePullDownRefresh": true,
"backgroundTextStyle": "dark"
}
具體怎麼用,因需求而定;以上方式,僅供參考。
rich-text解析html時如何讓圖片自適應
html.replace(/\<img/gi, '<img style="max-width:100%;height:auto"')
全局變量的定義和使用
1.在app.js中定義全局參數userInfo
2.在對應頁面js中 使用getApp().userInfo獲取
單個頁面配置導航欄爲自定義
1.剛開始百度 都說只能在app.json裏window對象下配置全局的 可是我的需求是隻是單獨的頁面需要配置 如果全局配置的話 其他頁面的樣式都要跟着修改 太麻煩了
2.然後查看了微信官方給出的文檔 說是支持單頁面配置 但對於導航欄樣式僅限7.0.0版本以後
小程序集成微信支付(前端)
1.用wx.login方法獲取code後換取openid(後臺獲取 微信安全限制不讓前端攜帶appid和secret去請求)
2.傳入openid和商品價格數量等參數生成商戶訂單
3.用訂單號獲取支付參數
4.拿到支付參數 用wx.requestPayment喚起支付完成支付操作
獲取openid接口:https://api.weixin.qq.com/sns/jscode2session?appid=APPID&secret=SECRET&js_code=JSCODE&grant_type=authorization_code
參考鏈接:https://www.cnblogs.com/oneall/p/9548448.html
自定義導航欄時iPhoneX適配問題
1.app.js globalData對象中定義全局屬性navHeight:0,然後在onLaunch中賦值
// 獲取手機系統信息
wx.getSystemInfo({
success: res => {
//導航高度
this.globalData.navHeight = res.statusBarHeight + 46;
}, fail(err) {
console.log(err);
}
})
2.在對應的頁面中獲取導航欄高度屬性值
this.setData({
navH: getApp().globalData.navHeight
})
3.爲導航欄添加樣式
<view class="tab" style='height:{{navH}}px;padding-top:calc({{navH-35}}px)'></view>
<view class="container" style='padding-top:calc({{navH}}px)'></view>
小程序中如何定義倒計時
1.util.js中定義方法並拋出
function getKillTime(killTime) {
// 計算目標與現在時間差(毫秒)
let time1 = new Date(killTime).getTime();
let time2 = new Date().getTime();
if (time1 > time2){
let mss = time1 - time2;
// 將時間差(毫秒)格式爲:天時分秒
let days = parseInt(mss / (1000 * 60 * 60 * 24));
let hours = parseInt((mss % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
let minutes = parseInt((mss % (1000 * 60 * 60)) / (1000 * 60));
let seconds = parseInt((mss % (1000 * 60)) / 1000);
// 返回需要的格式
return (hours < 10 ? '0' + hours : hours) + ":" + (minutes < 10 ? '0' + minutes : minutes) + ":" + (seconds < 10 ? '0' + seconds : seconds)
// return days + "天" + hours + "時" + minutes + "分" + seconds + "秒"
}else{
return false
}
}
module.exports = {
getKillTime: getKillTime
}
2.在對應的頁面中引入util.js
const util = require('../../utils/util.js')
data: {
killTime: "2019/07/25 19:59:00 GMT+0800", // 秒殺開始時間
killTimeShow: "" // 剩下的時間(天時分秒)
},
// 獲取秒殺時間 由於我這邊需要對時間做一些樣式處理 所以單獨拿出來時分秒
let timer = setInterval(() => { //注意箭頭函數!!
if (util.getKillTime(this.data.killTime)){
let hour = util.getKillTime(this.data.killTime).substr(0, 2)
let minute = util.getKillTime(this.data.killTime).substr(3, 2)
let second = util.getKillTime(this.data.killTime).substr(6, 2)
this.setData({
// killTimeShow: util.getKillTime(this.data.killTime)
killTimeShow: '<span class="span">' + hour + '</span>' + ':' + '<span class="span">' + minute + '</span>' + ':' + '<span class="span">' + second + '</span>',
});
}else{
clearInterval(timer);
}
}, 1000);
點擊按鈕分享指定頁面(小程序暫不支持分享指定h5鏈接出去,網上有說用web-view做的還是分享出去的是一個小程序,只不過裏面是h5的內容)
<button plain="true" class="item" data-id="shareBtn" open-type="share">
<image src="https://tb-images.oss-cn-shenzhen.aliyuncs.com/wxapp/wechat.png"></image>微信
</button>
/**
* 用戶點擊右上角分享
*/
onShareAppMessage: function (options) {
let id = options.target.dataset.id;
return {
title: '好友幫砍',
path: '/pages/bargain/help?id=' + id,
imageUrl: '', //用戶分享出去的自定義圖片大小爲5:4,
success: function (res) {
// 轉發成功
wx.showToast({
title: "分享成功",
icon: 'success',
duration: 2000
})
},
fail: function (res) {
// 分享失敗
},
}
}
小程序中給對象屬性賦值;給對象新增屬性賦值
let value = 'aaa.name'; // 給對象已有屬性賦值
let value2 = `aaa.${'age'}` // 給對象新增屬性並賦值 注意引號
this.setData({
[value]:'我是名字',
[value2]:'我是年齡'
})
事故性問題:小程序發版本,提交了好幾次都被駁回了,而我這邊又再進行新模塊的開發,每次都要回退到之前那個版本去,來回切換了有七八次,也比較着急,可能是開發工具裏有緩存,導致最終提交的代碼部分頁面樣式錯亂,我這邊看到審覈通過了也就直接發佈正式了,市場那邊接到命令後也就直接推廣宣傳了,但線上是有問題的這就比較尷尬,這裏需要注意一下,每次提交代碼之後,儘量在體驗版裏整體走一遍測一遍,確保沒有問題,再提交審覈,即便已經測試過了。
小程序與h5的交互(頁面跳轉及傳參)
1.小程序跳h5 直接採用web-view命令 設置src屬性即可 參數傳遞可採用url拼接的方式
2.h5跳小程序
第一步 引入微信開放js文件 這裏請注意版本 我最開始引入的是1.2.0 跳轉不成功
<script src="https://res.wx.qq.com/open/js/jweixin-1.3.2.js"></script>
第二步 判斷h5打開的環境 執行對應的操作
goDetail(id){
var smallPro=false;
wx.miniProgram.getEnv(function(res) {
console.log(res.miniprogram) // 是否在微信打開
if(res.miniprogram){
smallPro=true;
}else{
smallPro=false;
}
});
if(smallPro){
wx.miniProgram.navigateTo({
url:'../service/detail?id=' + id + '&areaId=' + 859, // 跳轉到小程序的服務詳情頁
});
}else{
this.getDevice().method.saveData('service',{ // 跳轉到app的服務詳情頁
serviceId:id,
areaId:859,
});
}
},
小程序中在線生成分享的h5鏈接二維碼
1.剛開始想到的是引用第三方js用代碼生成 完了再github上找了幾個發現引用到的項目裏 生成出來的二維碼怎麼掃都識別不了
2.想到了在線api去生成,網上搜索有很多,我選擇了兩個帶https的
https://api.qrserver.com/v1/create-qr-code/?size=150x150&data=http://www.baidu.com(未備案)
https://sapi.k780.com/?app=qr.get&data=http://www.xsyrz.cn&level=L&size=15(已備案)
過程中遇到以下幾個問題:
1.canvas繪製網絡圖片 在真機上不生效 需先下載至本地
2.下載二維碼圖片至本地時 在後臺配置合法域名時 提示未備案域名不可以
3.用已備案的地址生成二維碼 用canvas繪製出來時太過模糊 掃不出來 將size加大
4.url路由中含有#號 生成時不識別具體路徑 嘗試UrlEncode編碼的方式
小程序中繪製canvas並將其生成圖片保存在本地
// 繪製canvas
showModal(){
this.setData({
isHelp:true,
})
let self = this;
let ctx = wx.createCanvasContext('shareImg')
let headImg = wx.getStorageSync('headImg'); // 分享首圖
let codeImg = wx.getStorageSync('codeImg'); // 二維碼
ctx.fillStyle = "white";
ctx.fillRect(0, 0, 350, 400); // 繪製白色背景
ctx.drawImage(headImg, 0, 0, 350, 260); // 繪製首圖
ctx.fillStyle = 'black';
ctx.fillText(this.data.NickName + ' 喊你幫TA砍價', 20, 300); // 繪製黑色文字
ctx.drawImage('../../img/logo2.png', 20, 320, 45, 15); // 繪製logo
ctx.drawImage(codeImg, 180, 270, 75, 75)
ctx.draw(false, function () {
// 將canvas生成圖片 必須在draw回調中執行
wx.canvasToTempFilePath({
x: 0,
y: 0,
width: 350,
height: 450,
destWidth: 700,
destHeight: 900,
canvasId: 'shareImg',
success(res) {
console.log(res.tempFilePath)
self.setData({
shareImgSrc: res.tempFilePath
})
},
fail(err) {
console.log(err)
}
})
});
},
小程序保存網絡圖片和本地圖片到相冊
saveImage() {
// 如果是網絡圖片 需先下載至本地
wx.downloadFile({
url: this.data.shareImgSrc,
success(res) {
console.log(res.tempFilePath)
// 如果已生成本地圖片路徑 可直接到這一步保存
wx.saveImageToPhotosAlbum({
filePath: res.tempFilePath,
success(res) {
wx.showToast({
title: '保存成功'
});
},
fail(err) {
console.log(err)
},
})
},
})
},
日期格式帶 - 的話在ios不生效 需用.replace(/-/g, '/')將其轉成 /
小程序中如何清除計時器?如何清除多個計時器?
1.data中定義timer爲數組格式
2.每創建一個計時器 用this.data.timer.push(timer)
3.onHide和onUnload生命中週期中循環遍歷timer去清除
for (let i = 0; i < this.data.timer.length; i++) {
clearInterval(this.data.timer[i])
}
小程序中如何阻止事件冒泡?和h5有什麼區別?
舉例:外層容器有點擊事件進入詳情 容器內包含按鈕 點擊後只想調提醒接口而不進詳情
現象:傳統的bindtap點擊了內部按鈕 外部事件也會隨之觸發
解決:內部按鈕的提醒事件用catchtap
和h5阻止事件冒泡的區別:
$("button").click(function(event){
event.stopPropagation();
alert("The button element was clicked.");
});
$("div").click(function(){
alert("The div element was clicked.");
});
小程序web-view頁面 分享出去 打開空白
原因分析:分享時微信對url進行了編碼 導致打不開
解決辦法:onLoad中對url進行解碼處理 url: decodeURIComponent(options.url)
用戶拒接保存相冊權限後怎樣重新打開
問題出現:項目中有一個向用戶本地相冊保存圖片的權限 默認進來會打開彈框提示 是否授權 用戶點擊同意 成功保存 但點擊拒絕之後 再次保存就沒辦法了 官網查詢解釋如下:
所以 原有的wx.authorize重新獲取授權的方法並不能成功(網上很多人說的這種)
解決辦法:wx.openSetting調起小程序設置界面 引導用戶再次打開權限(但是現在好像官方好像不允許通過代碼去執行了,需要用戶通過點擊事件去執行)
<button open-type="openSetting" bindopensetting='handler'>點擊授權保存相冊權限</button>
小程序中如何上傳圖片到阿里雲oss
參考文檔:
https://blog.csdn.net/tang05709/article/details/80712107
https://help.aliyun.com/document_detail/92883.html?spm=a2c4g.11186623.6.1378.144149e8jsNag6
需求描述:
用戶通過小程序上傳圖片到阿里雲服務器(oss對象存儲),拿到對應的鏈接地址後,通過接口傳給後臺。
解決方案:
1.登錄阿里雲管理控制檯,配置 Bucket 跨域,設置允許跨域訪問
2.登錄小程序管理後臺,配置uploadFile合法域名,加入外網域名
3.下載上傳demo,upload.js中配置accessid、accesskey、host,並打印new_multipart_params參數
4.通過html測試上傳圖片 控制檯裏拿到key、policy、OSSAccessKeyId、signature等參數
(以上四步參考文檔裏都有,講的很詳細,可以對照看一下)
5.小程序中拿取照片並上傳,代碼如下
// 上傳照片
upload(e) {
let self = this;
wx.chooseImage({
success: function (res) {
let imgSrc = res.tempFilePaths[0];
let fileType = imgSrc.split('.')[imgSrc.split('.').length-1];
let folderName = 'app-contract/test/';
let key = folderName + new Date().getTime() + '.' + fileType;
let imgUrl = 'https://tb-images.oss-cn-shenzhen.aliyuncs.com/' + key
wx.uploadFile({
url: 'https://tb-images.oss-cn-shenzhen.aliyuncs.com',
filePath: imgSrc,
name: 'file',
formData: {
'name': imgSrc,
'key': key,
'policy': 'xxxxx',
'OSSAccessKeyId': 'xxxxx',
'signature': 'xxxxx',
'success_action_status': '200',
},
success: function (res) {
console.log(res)
self.uploadImage(imgUrl);
},
fail: function (res) {
console.log(res)
},
})
}
})
},
微信單擊雙擊事件並存
<image mode='aspectFill' data-url='{{item}}' src="{{item}}" bindload="swiperHeight" style='width:100%;height:100%;' bindtap='multipleTap' bindtouchstart="touchStart" bindtouchend="touchEnd"></image>
// 按鈕觸摸開始觸發的事件
touchStart(e) {
this.touchStartTime = e.timeStamp
},
// 按鈕觸摸結束觸發的事件
touchEnd(e) {
this.touchEndTime = e.timeStamp
},
// 單擊預覽圖片 雙擊心動
multipleTap(e) {
var self = this
// 控制點擊事件在350ms內觸發,加這層判斷是爲了防止長按時會觸發點擊事件
if (self.touchEndTime - self.touchStartTime < 350) {
// 當前點擊的時間
var currentTime = e.timeStamp
var lastTapTime = self.lastTapTime
// 更新最後一次點擊時間
self.lastTapTime = currentTime
// 如果兩次點擊時間在300毫秒內,則認爲是雙擊事件
if (currentTime - lastTapTime < 300) {
console.log("雙擊事件被觸發")
// 成功觸發雙擊事件時,取消單擊事件的執行
clearTimeout(self.lastTapTimeoutFunc);
wx.showModal({
title: '示愛成功',
content: '對方將會收到您的心動提示',
showCancel: false
})
self.setData({
isLove:true
})
} else {
// 單擊事件延時300毫秒執行,這和最初的瀏覽器的點擊300ms延時有點像。
self.lastTapTimeoutFunc = setTimeout(function () {
console.log("單擊事件被觸發")
wx.previewImage({
current: e.currentTarget.dataset.url, // 當前顯示圖片的http鏈接
urls: self.data.bannerList // 需要預覽的圖片http鏈接列表
})
}, 300);
}
}
},