mission7-制作小程序

本次小程序使用 mpvue+iview 制作,期间遇到了不少坑,这里总结如下:

项目搭建

1.安装mpvue环境

1
2
3
4
5
vue init mpvue/mpvue-quickstart my-project

cd my-project
npm install
npm run dev

2.安装iview组件

github下载组件,然后将dist目录拷贝到static文件夹下,然后需要注意的是小程序要将详情 => ES6转ES5打开

修改navigationBar信息

在页面同级文件夹下创建main.json文件,具体配置和小程序api一致

页面新建、跳转

新建页面

除了需要在src/pages文件夹内按照格式创建index.vuemain.js文件外,还需要在src/app.json中添加页面路径信息

页面跳转

使用wx.navigateTo方法进行页面跳转,路径参照src/pages文件夹内页面存放路径

iview组件样式修改

在页面内想要修改组件样式,即使加/deep/ 或者全局样式也不能修改,暂时没有好的解决办法,只能在源码内进行修改

i-swipeout组件相关事项

右侧滑动按钮数据格式必须固定为:

1
2
// 貌似必须是这样的,否则不会生效,我在这里设置了
[{},{}]

自定义右侧样式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<i-swipeout
i-class="i-swipeout-demo-item"
:operateWidth="150">
<!--operateWidth设定右侧按钮宽度-->
<!--内容插槽-->
<view slot="content">
<view class="i-swipeout-des">
<view class="i-swipeout-des-h2">第七个小矮人</view>
<view class="i-swipeout-des-detail">乐观善良的7个小矮人原本过着简单快乐的生活,不料诅咒公主的巫婆利用小矮人进入.</view>
</view>
</view>
<!--右侧按钮插槽-->
<view slot="button" class="i-swipeout-demo-button-group">
<view class="i-swipeout-demo-button">删除</view>
</view>
</i-swipeout>

slot

目前我是用的mpvue@1.0.11版本,关于 slot存在以下问题:

  • 同一个组件不支持多个插槽!!!

删除 pages 页面后的问题

mpvue 开发模式是每次保存代码修改后自动打包到 dist 文件夹下的,但是删除页面后,dist 内还保留原页面的打包文件,会导致小程序报错

事件相关

小程序事件

原生 Evnet 内容都被整理到了 mp 对象下,例如:

用户信息获取e.detail.userInfo变成了e.mp.detail.userInfo

事件修饰符

不支持.self修饰符

如何实现”self”

小程序是没有办法获取 dom 元素的,但是可以获取元素的 id, 例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
<cover-view
id="modal"
@tap="closeModal">
<cover-view>点我不会关闭模态框</cover-view>
</cover-view>
<script>
closeModal (e) {
console.log(e);
if (e.currentTarget.id === 'modal') {
this.$emit('update:visible', false);
}
}
</script>

cover-view && cover-image

坑一: css 样式并不能全部支持,只支持基本的定位 scale rotate opacity 等(不支持 background-image,只能是用 cover-image)

坑二: cover-image 不显示的原因:

  • 不支持绝对路径,只能是用相对路径
  • 使用不支持的 css 属性有可能导致图片不显示

引入 echarts 制作地图图表

npm i mpvue-echarts echarts 安装组件

相关代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
<template>
<div class="echarts-wrap">
<mpvue-echarts
id="mychart-dom-area"
canvas-id="mychart-area"
:echarts="echarts"
:onInit="onInit"></mpvue-echarts>
</div>
</template>
<script>
import * as echarts from 'echarts'
// import * as echarts from '_/echarts.min.js' // 定制的 echarts 仅支持 map 功能
import mpvueEcharts from 'mpvue-echarts'
import geoJson from './china' //地图数据 可以在https://github.com/apache/incubator-echarts/ 找所需的地图数据使用
function initChart(canvas, width, height) {
const chart = echarts.init(canvas, null, {
width: width,
height: height
});
canvas.setChart(chart);

echarts.registerMap('china', geoJson);

const option = {};
chart.setOption(option);

return chart; // 返回 chart 后可以自动绑定触摸操作
}
export default {
components: {
mpvueEcharts
},
data () {
return {
echarts,
onInit: initChart
}
}
}
</script>
<style>
.echarts-wrap {
width: 100%;
height: 300px;
}
</style>

生命周期

所有页面内的 created 周期内的方法会在小程序页面打开时一次性全执行.

map 组件

MapContext.includePoints(Object object)

padding 属性的值一定要写成[number, number, number, number]这样的,虽然安卓机只能识别第一个,上下左右padding值一致,但是iphone必须写满四个值才行

regionchange事件绑定

因为使用了 mpvue 编译,该事件要绑定成<map @regionchange="regionChange" @begin="regionChangeBegin" @end="regionChangeEnd"><map>

只绑定其中一个事件是不生效的

polyline

数组中的点位数量不要太多,否则会导致小程序崩溃,具体数量自己衡量,每个机型的也不一样。

ios系统开启省电模式后,可以处理的点位数量将变少

marker

如果给 marker 添加 name 属性的话,就会有一个默认的点击弹出 name 效果,类似 callout 但巨丑无比。。。 当时还很纳闷这个功能怎么来的。。。

获取用户信息

getUserInfo获取用户信息权限,原来可以直接使用 wx.getUserInfo() 获取,现在必须使用<button open-type="getUserInfo" lang="zh_CN" @getuserinfo="onGotUserInfo">确定</button>按钮来获取.注意!!!获取权限后,即使刷新页面还是再次登录,只要没有重新小程序再次调用 wx.getUserInfo() 的话都是会失败的?,解决方法是使用 onGoutUserInfo 作为首次获取信息的方法,后续再打开小程序时走 wx.getUserInfo 中的方法

mpvue 页面关闭后再次打开会保留上次关闭的数据

原因是 mpvue 多页面共用了一个 vm 对象,解决方法可以参考:

https://github.com/Meituan-Dianping/mpvue/issues/140

scroll-view

滚动组件中使用 absolute 会失效,解决方式需要置顶的内容放在滚动组件外面.

不知名 bug

函数太乱(?) 会导致循环不执行,下面这个 map 就神奇的不循环了

1
2
3
4
5
6
7
8
9
10
11
[a, ...b].map(item => {
//...
if () {
//...
} else if () {
//...
} else {
//...
}
//...
)

cover-img 设置 rotate 会导致图片变大…

https://developers.weixin.qq.com/community/develop/doc/000aa05c39cff86510b766ed15b400?highLine=rotate

很多时候出现无厘头的 bug 需要让大脑放空一下,出去透透气,等让代码冷静下来,就好了:)

slot

写下这段时,我使用的是 mpvue 1.0.13 版本,在 slot 中并不能使用动态数据,如:

1
2
3
4
<my-comt>
<div v-if="show">看不看得见</div>
<div>看得见</div>
</my-comt>

当动态控制 show 为 ture 值时,视图也依然不会显示。

1
2
3
<my-comt>
<input v-model="value"/>
</my-comt>

当动态控制 value 值为其它值时,视图不会修改。

地图组件中 marker 无法使用网络图片的问题

需要使用 wx.downloadFile() 方法先将图片下载下来再使用

setData 数据更新问题

参考文章:在mpvue中使用map如何避坑

mpvue 中更新数据是将 data 中的所有数据同步到小程序中,可能会导致以下 bug:

  1. 导致某些未修改的数据更新
  2. 导致小程序数据崩溃卡死

解决办法:

1
2
3
4
5
6
7
8
9
10
//数据写入方式改为原生方法:
this.$mp.page.setData({
'$root[0].latitude': this.$data.latitude,
'$root[0].longitude': this.$data.longitude,
'$root[0].markers': this.$data.markers,
'$root[0].groupId': this.$data.groupId,
'$root[0].selected': this.$data.selected,
'$root[0].showMarkers': showMarkers,
'$root[0].polyline': polyline,
})

canvas 绘制海报

部分安卓手机使用canvasToTempFilePath生成海报图片时,会出现各种奇怪的排版错误。

解决方法,添加定时器,例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
ctx.draw(
false,
setTimeout(() => {
wx.canvasToTempFilePath({
x: 0,
y: 0,
width: W,
height: H,
destWidth: 4 * W, //为了解决清晰度问题,输出图像的尺寸为源图像的4倍
destHeight: 4 * H,
canvasId: 'shareImg',
success: res => {
/* 这里 就可以显示之前写的 预览区域了 把生成的图片url给image的src */
console.log('draw succ==============', res.tempFilePath);
},
fail: function (res) {
console.log('darw fail==============', res);
}
})
}, 300) //定时器延时给大一些,最少200-300才行
)

坚持原创技术分享,您的支持将鼓励我继续创作!