因为我这个小程序是用mpvue框架搭的,所以下面一些示例代码中会含有mpvue语法,仅供参考,不喜勿喷
1.分包
小程序最多只支持8M大小的项目,有时候项目比较庞大,则需要使用分包,而分包大小又不能超过2M
下面给出分包的写法
在app.json中
{
"pages": [ // 这是主包的文件
"pages/home/main",
"pages/login/main"
],
"subpackages": [ // 这是分包的文件
{
"root": "pages/exam/",
"name": "exam",
"pages": [
"main",
"examPaper/main",
"exercise/main"
]
}
]
}
跳转到分包的路径是root+pages,如
wx.navigateTo({ url: '/pages/exam/examPaper/main' })
注意,带有底部导航栏中的页面(也就是配置在app.json中tabBar中的页面)必须写在主包中
2.生命周期
我这里简单说一下onLoad,onUnload,onShow,onHide的几种常见场景
a. 小程序由前台进入后台(即用户点击右上角退出小程序或者按home键离开微信),触发onHide
b. 带有底部导航栏中的页面互相切换时(wx.switchTab),触发onShow与onHide
c. 使用wx.navigateTo或者wx.redirectTo的切换,页面显示触发onLoad、onShow,离开页面触发onUnload(不会触发onHide)
d. 由普通页面使用wx.switchTab切换到带有底部导航栏中的页面时,如从登录页切换至首页,登录页没有触发生命周期,首页触发onLoad,onShow
e. 由父界面跳转到子页面时,父页面触发onHide,子界面触发onLoad,onShow。从子页面返回父页面时,子页面onUnload,父页面onShow
3.路由跳转及传参
wx.navigateTo({ url: '/pages/logs/main?id=1' })
得到参数:$root.$mp.query.id
由普通页面跳转到带有底部导航栏的页面是用wx.switchTab,普通跳转用wx.navigateTo
(相当于vue中的this.$router.push
),wx.redirectTo
(相当于vue中的this.$router.replace
),wx.navigateBack({ delta: 1 })
(相当于vue中的this.$router.go(-1)
)
4.获取元素节点信息
wx.createSelectorQuery().select('#test').boundingClientRect((rect) => {
console.log(rect)
}).exec()
5.下拉刷新上拉加载
首先需在app.json中做如下配置才能使用onPullDownRefresh,onReachBottom两个事件
"window": {
"enablePullDownRefresh": true
}
onPullDownRefresh() {
// dosomething
wx.stopPullDownRefresh() // 为解决下拉之后页面迟迟没有回弹,最好加上这一行
},
onReachBottom() {
// dosomething
}
如不要下拉刷新上拉加载,可在当前页的配置文件main.json中将enablePullDownRefresh关闭
{
"enablePullDownRefresh": false
}
6.图片懒加载
6.1 图片加载错误时用默认图片代替
<img :src=’图片地址’ @error=’errorImg’>
errorImg(){
// 将加载失败图片替换为默认图片
}
6.2 懒加载
方法一:使用IntersectionObserver
小程序提供了一个IntersectionObserver的API,可以用来监听元素与页面的相交情况
可查看微信相关文档: https://developers.weixin.qq.com/miniprogram/dev/api/wxml/wx.createIntersectionObserver.html
<div class='scroll-view'>
<div class='home'></div>
</div>
// 判断class='home'的元素是否出现在屏幕中
onLoad() {
const _observer = wx.createIntersectionObserver()
_observer.relativeTo('.scroll-view')
.observe('.home', (res) => {
console.log(res.intersectionRatio > 0) // 如果大于0则表示相交
})
}
//或者
onLoad() {
const _observer = wx.createIntersectionObserver()
_observer.relativeToViewport()
.observe('.home', (res) => {
console.log(res.intersectionRatio > 0)
})
}
方法二:使用onPageScroll
onPageScroll: throttle(
function(e) {
wx.createSelectorQuery().select('.home').boundingClientRect((ret) => {
if (ret.top <= wx.getSystemInfoSync().windowHeight) { // 判断是否在显示范围内
// dosomething
}
}).exec()
}, 100
),
throttle(fn, interval) { // 节流
let enterTime = 0 // 触发的时间
const gapTime = interval || 300 // 间隔时间,如果interval不传,则默认300ms
return function() {
const context = this
const backTime = new Date() // 第一次函数return即触发的时间
if (backTime - enterTime > gapTime) {
fn.call(context, arguments)
enterTime = backTime // 赋值给第一次触发的时间,这样就保存了第二次触发的时间
}
}
}
7.动态改变顶部导航栏的文字
导航栏上方标题是通过main.json配置的
{
"navigationBarTitleText": "首页"
}
有时同一个页面根据页面内容会有不同的标题,此时需要动态配置导航栏标题名
wx.setNavigationBarTitle({
title: title
})
有时希望整个页面布满屏幕,没有导航栏文字,如下图
此时可以在当前页面的main.json中配置
{
"navigationStyle": "custom"
}
8.textarea样式穿透
小程序的textare中的z-index层级是最高的,任何元素都无法遮住。这里说一下思路,就不贴代码了。
做一个跟当前textarea一样的div(简称克隆div),textarea内容也展示到div中。当对话框弹出时,textarea隐藏,克隆div展示,对话框关闭时,textarea展示,克隆div隐藏
9.滚动弹出层时,弹出层下方的内容也会滚动
方法一:改变scroll-y的值<scroll-view :scroll-y="scrollY">
弹出层出现时scrollY=false,弹出层关闭时scrollY=true
方法二:不需要滚动时将页面样式设为position:fixed,但此方法会使页面滚到到顶部,介意慎用
方法三:将滚动页面最外层加上此属性:catchtouchmove=“return”
10.键盘弹出
页面下方有一个操作栏,当键盘弹起时,操作栏要定位在键盘上方,此时要用到小程序的一个事件,此为小程序文档截图
https://developers.weixin.qq.com/miniprogram/dev/component/input.html
写法参考:
<textarea @keyboardheightchange="keyboardheightchange"</textarea>
<div class="bottom-content" :style="{bottom: bottom + 'px'}">操作栏</div>
keyboardheightchange(val) {
this.bottom = val.target.height
}
focus(val) { // 也可以用focus跟blur
this.bottom = val.target.height
}
blur() {
this.bottom = 0
}
11.wx-parse 用来解析html的插件,还挺好用的,有图片的话,点击图片有预览的效果
https://github.com/icindy/wxParse
12.转发
onShareAppMessage: function(res) {
return {
title: '',
path: '/pages/home/main',
success: function(res) {
},
fail: function(res) {
}
}
}
13.上传图片
wx.chooseImage({
count: 1, // 默认9
sizeType: ['original', 'compressed'], // 可以指定是原图还是压缩图,默认二者都有
sourceType: ['album', 'camera'], // 可以指定来源是相册还是相机,默认二者都有
success: (chooseImageRes) => {
const tempFilePaths = chooseImageRes.tempFilePaths[0]
wx.uploadFile({
url: url,
filePath: tempFilePaths,
name: 'fileData',
header: { 'Content-Type': 'multipart/form-data' },
formData: {
method: 'POST'
},
success: (res) => {
//dosomething
}
})
}
})
14.预览图片
wx.previewImage({
urls: [imgSrc] // 需要预览的图片http链接列表
})
15.预览pdf文档
wx.downloadFile({
url: url,
success(res) {
wx.openDocument({
filePath: res.tempFilePath,
success(res) {
},
fail() {
console.log('无法打开此文档,因为不支持该类型或已损坏')
}
})
}
})
16.扫码
如果扫码是要打开一个网页的话,可以单独做一个只有webview的页面,跳转到此页面,传入url即可
wx.scanCode({
onlyFromCamera: false,
scanType: ['qrCode', 'barCode'], // 可以指定扫二维码还是一维码,默认二者都有
success: function(res) {
const resultStr = res.result
if (resultStr.indexOf('https') === 0) {
wx.navigateTo({ url: `/pages/home/webView/main?url=${resultStr}` }) // 跳转到webview的页面
} else {
// dosomething
}
}
})
<div>
<web-view :src="url"></web-view> // url通过onLoad(){ this.url = this.$root.$mp.query.url }获取
</div>