小程序开发的一些想法
前言
对于初学者,最好的入门方式就是通读官方文档,不建议记api,用的时候可以快速找到就好
- 不推荐使用原生开发的几点理由
- 开发效率低
- 频繁setData有性能消耗问题
3.wx.request存在并发量限制问题(最大并发量不能超过10)
关于尺寸
不支持vue-router
- 原生和mpvue官方不支持,这里是一个在mpvue基础上改造来的框架,支持vue-router类语法(对mpvue做了扩展) 猛撮这里.
组件支持自定义类继承语法
<!-- index.vue -->
import BasePlatePage from '@/utils/basePlatePage'
export defalut new BasePlatePage({
data(){},
methods:{},
...
})
- 类继承方式扩展了组件能力,可以阻塞生命周期方法(一般是onLoad),来实现一些预备逻辑,例如授权
- 按需引入
不支持运行环境判断
- 但是有变通的办法
小程序中__wxConfig.envVersion可以用来区分小程序体验版,开发板,正式版.
envVersion 类型为字符串
envVersion: 'develop', //开发版
envVersion: 'trial', //体验版
envVersion: 'release', //正式版
这样我们就可以变通的来实现小程序中动态切换域名,避免手动注释切换的方式.
<!-- request.js -->
let envVersion = __wxConfig.envVersion || 'develop';
const url = envVersion === 'develop' ? Store.state.testUrl ? Store.state.baseUrl
- 通用
分包加载
- 主流方式
1.创建目录
pages 目录同级创建分包目录 moduleA->ma1.vue
2.配置
<!-- pages.json -->
{
"pages": [ //pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages
{
"path": "pages/index/index",
"style": {
"navigationBarTitleText": "uni-app"
}
},
{
"path": "pages/index/todoList",
"style": {
"navigationBarTitleText": "todolist"
}
}
],
"subPackages": [{
"root": "moduleA",
"pages": [{
"path": "ma1",
"style": {
"navigationBarTitleText": "ma1"
}
}]
}],
"globalStyle": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "uni-app",
"navigationBarBackgroundColor": "#F8F8F8",
"backgroundColor": "#F8F8F8"
}
}
- mpvue-quickstart 框架下分包的使用方式
生命周期方法
- mpvue支持vue所有生命周期方法和小程序所有生命周期方法
- 页面跳转传参,只能在在onLoad方法以及之后方法中获取,onLoad中为事件参数e,onLoad之后方法通过
this.$root.$mp.query
<!--index.vue -->
export default {
onLoad(e) {
console.log(e,'onLoad') //e:上个页面传递的参数对象{a: 1,b:2}
},
onShow() {
console.log('onShow')
},
onReady() {
console.log('onReady')
},
created () {
console.log(this.$root.$mp.query,'created') //获取不到参数,并且会报错,原因是页面传递的参数最早是从onLoad中获取
},
mounted() {
console.log(this.$root.$mp.query,'mounted') //可以获取到页面传递的参数
}
}
打印顺序依次为 created,onLoad,onShow,onReady,mounted
模板语法支持情况
扫码进入指定页面
1.前端给后台指定页面路径,后台进行配置,生成二维码 2.前端在onLoad中使用decodeURIComponent方法解析获取
onLoad(params) {
if (params && params.scene) {
this.id = decodeURIComponent(params.scene).split('=')[1]; //扫码进入获取二维码携带的参数
} else {
this.id = this.$route.query.id //普通路由跳转,携带的参数
}
}
转发
1.点击右上角"转发"按钮转发 2.页面内发起转发
<!-- share.vue -->
<template>
<div>
<button class="share-btn" open-type="share">分享一下</button>
</div>
</template>
export default {
data() {
return {
shareImageURL: "https:xxx" //图片地址
}
},
methods: {
},
//该方法为转发的核心方法,必须要有,否则不会触发转发
onShareAppMessage(from){
if (res.from === 'button') {
// 来自页面内转发按钮
console.log(res.target)
}
return {
title : '小程序购物' , //转发标题,默认小程序名称
path : '/pages/share' , //转发路径,默认当前页面 path ,必须是以 / 开头的完整路径
imageUrl : this.shareImageURL //自定义图片路径,支持网路路径和本地路径,png,jpg格式,默认使用截图
}
},
}
request请求
wx.request
- 小程序原生请求api,没啥说的,具体可以看wx.request
wx.request({
url: 'test.php', //仅为示例,并非真实的接口地址
data: {
x: '',
y: ''
},
header: {
'content-type': 'application/json' // 默认值
},
success (res) { //接口请求成功的回调函数
console.log(res.data)
},
fail(res) { //接口请求失败的回调函数
console.log(res)
},
complete(res) { //接口调用结束的回调,无论成功,失败都会执行
console.log(res)
)
fly.io
- 官方描述:一个支持所有JavaScript运行环境的基于Promise的、支持请求转发、强大的http请求库。可以让您在多个端上尽可能大限度的实现代码复用。
<!-- 栗子 -->
//token
import auth from './auth'
import Store from '../store'
const Fly = require('flyio/dist/npm/wx')
const fly = new Fly
const serviceURL = Store.state.domain;
const baseConfig = {
method : 'post' ,
timeout : 30000 ,
parseJson : true ,
withCredentials:false
}
fly.config = baseConfig;
//请求拦截
fly.interceptors.request.use((config)=>{
//请求头
let token = auth.getToken();
config.baseURL = serviceURL;
config.headers['token'] = token;
return config
})
//响应拦截器
fly.interceptors.response.use(response => {
// 特殊提示
if(Number(response.data.error) === 1){
//console.error(response)
wx.showModal({
title: '出错啦',
content: response.data['error_reason'] ,
showCancel: false
})
return { fail : true }
}
// 出错了
if (Number(response.data.error) !== 0) {
console.error(fly.config)
console.error(response)
wx.hideLoading();
wx.showModal({
title: '温馨提示',
content: response.data['error_reason'] ,
showCancel: false
})
return { fail : true }
}
return response.data && response.data.data || { success: true };
},error=>{
wx.showModal({
title: '出错啦',
content: '服务器开小差了~',
showCancel: false
})
// 必须返回响应数据对象,否则后续无法对响应数据进行处理
return error;
})
export default fly
下拉刷新
- 1.app.json文件进行enablePullDownRefresh属性配置
- 2.当前页面书写onPullDownRefresh方法(下拉刷新操作会自动触发该方法)
<!--app.json -->
{
"pages": [
{
"path": "pages/index",
"config" : {
"enablePullDownRefresh": true, //当前页面是否允许下拉刷新
"navigationBarTitleText": "首页"
}
},
{
"path": "pages/counter"
},
{
"path": "packageA/logs",
"subPackage": true
}
],
"window": {
"backgroundTextStyle": "light",
"navigationBarBackgroundColor": "#fff",
"navigationBarTitleText": "WeChat222",
"navigationBarTextStyle": "black"
}
}
<!-- index.vue -->
export default {
data() {
return {}
},
methods: {},
onPullDownRefresh: function() {
// Do something when pull down.
setTimeout(() => {
wx.stopPullDownRefresh(); //停止当前页面下拉刷新,这句代码必须写,否则会出现下拉后不返回的现象
}, 1500);
},
}
上拉加载
- 这个方法一般不需要app.json文件中配置,但是有的手机上会出现触底后方法不触发的现象,因此,为了解决这个问题,然后在app.json里面设置下触发距离
<!--app.json -->
{
"pages": [
{
"path": "pages/index",
"config" : {
"enablePullDownRefresh": true, //当前页面是否允许下拉刷新
"navigationBarTitleText": "首页",
"onReachBottomDistance": 50 //设置触发距离,在触发距离内滑动期间,本事件只会被触发一次。
}
],
"window": {
"backgroundTextStyle": "light",
"navigationBarBackgroundColor": "#fff",
"navigationBarTitleText": "WeChat222",
"navigationBarTextStyle": "black"
}
}
<!-- index.vue -->
export default {
data() {
return {}
},
methods: {},
onReachBottom: function() {
// Do something when page reach bottom.
},
}
scroll-view
- scroll-view 是一个比较消耗性能的组件,遇到顶部带有navBar切换有长列表(分页加载)的页面首先考虑使用定位+页面滚动方式,实在不行再考虑使用该方法
部分原生组件的层级问题
- 小程序中部分原生组件,例如video,map等存在层级最高且无法通过z-index降低的问题,可以放一张图片进行占位,然后点击图片跳转到一个新页面播放视频或者展示地图
- cover-view和cover-image 覆盖层
富文本解析
插入图表
- 备注
1.mpvue中新增的页面,需要重新 npm run dev 来进行编译
2.同样可以使用ref
注意:虽然小程序中可以使用ref,但是具有局现象3.不支持动态组件<!--index.vue--> <div ref="di"></div> <!--不可以--> <list ref="list"></list> <!--可以--> <script> mounted() { console.log(this.$refs.di) //输出一个空 {},因此拿不到元素,可能是和小程序中没有dom概念(无法用document.的方式获取元素)有关吧,后面有时间具体研究下,不过当ref加载组件上,用法正常. console.log(this.$refs.list) //会输出当前组件对象 } </script>