0%

uni-app 开发记录

记录使用uni-app开发(填坑)过程中的问题和解决方法

创建项目

使用正式版创建项目:

1
$ vue create -p dcloudio/uni-preset-vue jarvis-uni-app

运行项目:

1
npm run dev:app-plus

Webstorm 支持组件import语法

我们在import一个组件的时候是import xxx from '@/components/xxx';。这时候webstorm会红色报警: Cannot find module '@/components/xxx' or its corresponding type declarations.

是webstorm无法识别@路径导致的,我们需要告诉Webstorm这个@路径指啥。

在根目录下定义alias.config.js

1
2
3
4
5
6
7
8
9
10
11
12
/**
* 本文件对项目无任何作用,仅作为 WebStorm 识别别名用
* */
const resolve = dir => require('path').join(__dirname, dir);

module.exports = {
resolve: {
alias: {
'@': resolve('src')
}
}
};

然后进入 WebStorm preferences -> Language & Framework -> JavaScript -> Webpack,选择我们刚创建的alias.config.js这个文件即可。

再次回到引入组件的地方,发现不仅飘红消失了,而且我们在输入组件路径的时候还会自动提示,非常好~

启用Scss

为了方便开发,我们一般会使用预处理Scss类型的css。我们在项目中启用也很方便,直接在style中:

1
2
<style lang="scss" scoped>
</style>

即可,就可以在样式中使用scss来开发,但是慢着,为啥会报错???

我们还需要安装scss处理的包:node-sassscss-loader

直接:

1
2
yarn add node-sass -D
yarn add sass-loader -D

然后再次运行,OK~

Webstorm支持rpx

Webstorm是不支持rpx的,在使用rpx的地方都是难看的飘红,我们前面已经启用了scss,那么可以定义方法来解决这个问题。

定义一个方法:

1
2
3
4
// 定义函数 rpx
@function rpx($value) {
@return $value * 1rpx;
}

然后在使用的地方:

1
2
3
body{
width: rpx(30)
}

因为这个是全局使用的,而uni.scss是全局的样式,是不需要引入即可使用的,这不是巧了么?

可以把上面定义的方法放入uni.scss文件的最下面。然后在组件中使用rpx函数即可。

HBuild运行项目到小程序开发者工具

需要去小程序开发者工具调试,在HBuild里面运行到小程序开发者工具中:
uniapp-development

发现输出里面报错:

1
2
[error] IDE service port disabled. To use CLI Call, please enter y to confirm enabling CLI capability, or manually open IDE -> Settings -> Security Settings, and set Service Port On.
[error] 工具的服务端口已关闭。要使用命令行调用工具,请在下方输入 y 以确认开启,或手动打开工具 -> 设置 -> 安全设置,将服务端口开启。

刚开始细看这个提示,只是看中文是说下面输入y,然而输了也没反应,最后查了后才发现,是需要去小程序开发者工具中,点击上面的设置 -> 安全设置,然后打开服务端口:
uniapp development

然后再回到HBuild中,如果前面运行的话就先停掉运行,然后重新运行到小程序开发者工具。发现是OK的。

HBuild 运行到MUMU模拟器(MAC)

MUMU是一款安卓模拟器,有mac版和pc版,还是比较方便的。那么如何将它和HBuild的uniapp链接起来呢?

首先我们需要知道adb(Android Debug Bridge 安卓调试桥接工具)。在mac中我已安装了Android Studio,所以可以直接使用adb命令,但是在shell中输入后显示没有这个命令。真尴尬。

首先进入目录:~/Library/Android/sdk/platform-tools,可以看到有adb这个文件的。然后我们需要将这个路径假如到.bash_profile中:

1
export PATH=${PATH}:~/Library/Android/sdk/platform-tools

保存后,重新加载shell: source ~/.bash_profile。然后再在shell里面试一下adb命令:

1
2
3
4
$ adb
Android Debug Bridge version 1.0.41
Version 30.0.1-6435776
Installed as /Users/tonyyang/Library/Android/sdk/platform-tools/adb

可以看到,现在识别了。

MUMU的mac版adb端口是5555,所以我们来尝试用adb命令链接下:

1
2
$ adb connect 127.0.0.1:5555
connected to 127.0.0.1:5555

可以看到一切正常。

然后回到HBuild中,依次点击运行 => 运行到手机或模拟器 => Android模拟器端口设置(或者ADB路径设置)。找到Android模拟器端口设置,将5555填入即可。
uniapp 端口

保存后再次点击运行 => 运行到手机或模拟器 ,即出现可运行的设备。完成。

然后可以在编辑器中保存,然后模拟器中会热加载,非常好~。

小程序Canvas绘制不显示的问题

一个特殊业务需要绘制canvas,发现在H5运行的时候是可以显示的,在小程序开发者工具里面是不显示绘制的:

1
<canvas :style="'width:' + canvas.width + 'px; height:' + canvas.height + 'px;'" type="2d" canvas-id="schedule"></canvas>

这样不显示,查了好久,我以为是动态改变大小之类的问题,后面是在是没法子,使用uniapp官网例子搞了一下,发现是可以显示的。

最后尝试出来,是因为在Canvas里面定义了type="2d"导致的,我本来看了下小程序的文档,发现是推荐使用2d模式的,去掉就没问题了:

1
<canvas :style="'width:' + canvas.width + 'px; height:' + canvas.height + 'px;'"  canvas-id="schedule"></canvas>

虽然显示没问题了,但是在小程序开发者工具里面运行的时候,又提示我需要加上type="2d",尴尬的一批啊!!!

就酱!

小程序Cookie传递

微信小程序的wx.request网络请求不支持传统的Cookie。我只是一个小前端啊,现有业务本身就是通过Cookie来获取登录状态的,我总不能让人家不用Cookie来用Token吧,得解决这个问题。

为什么我们在Web或H5中不需要特别处理Cookie呢?是因为在普通的Web中我们不需要处理Cookie是因为响应头里面有Set-Cookie字段后,之后的每次请求,浏览器都会带着该Cookie,在请求头里将该Cookie传给后端。

那其实很简单,核心思想就是,我们在登录接口请求成功后,将Set-Cookie响应头中的Cookie保存在本地,然后在下次请求的时候,手动将这个Cookie塞到请求头中的Cookie中去。

第一步:从Set-Cookie中获取Cookie并保存:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
 // #ifdef MP-WEIXIN
if (response.header['Set-Cookie']) {
// 需要保存cookie
const cookie = response.header['Set-Cookie'].split(';')[0];
uni.setStorageSync('cookie', cookie);
// 我用的一个http的库的特别处理方式
if (cookie) {
http.setConfig((config) => {
config.header.Cookie = cookie;
return config;
});
}
// http.config.header.cookie = response.header['Set-Cookie']
}
// #endif

因为这是小程序中特别处理的,所以加上uniapp的特有注释来区分平台。

第二步:在发送请求的时候读取Cookie并塞到请求头中:

1
2
3
4
5
6
7
8
9
// #ifdef MP-WEIXIN
const cookie = uni.getStorageSync('cookie');
if (cookie) {
http.setConfig((config) => {
config.header.Cookie = cookie;
return config;
});
}
// #endif

搞定!

在app中获取版本号

首先定义version字段用来在页面中展示,然后我们的获取版本号的代码为:

1
2
3
4
5
plus.runtime.getProperty(plus.runtime.appid,(wgtinfo)=>{
console.log(JSON.stringify(wgtinfo));
console.log(wgtinfo.version);//应用版本号
this.version = wgtinfo.version;
})

这样获取到的版本号为:1.0.0这样子的。

下拉刷新页面

首先需要在page.json里面找到当前页面的pages节点,然后在style选项中开启enablePullDownRefresh

然后在页面中定义函数:onPullDownRefresh(该函数和method同级)。

我一般是将进入页面需要做的处理都放在一个init方法中,然后下拉刷新的方法中就很简单的调用下init方法即可,然后记得在init中关掉下拉刷新的loading。

代码示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
export default {
methods: {
init() {
// 其他处理
// 在页面加载完成后关掉下拉加载的loading
uni.stopPullDownRefresh();
},
// other function
},
onPullDownRefresh() {
// 下拉加载的逻辑
this.init();
},
onLoad() {
// 进入页面后的逻辑
this.init();
}
}

在dom中绑定类

我们常用的通过集中不同的情况绑定显示什么样式可以用:class="{className: true}"这样来绑定,但是当类有好几个,并且判断条件有点复杂的时候这样写就很写也很难维护。

那可不可以绑定一个方法,这个方法返回对应的类名结构的对象呢?

来尝试下,先定义类,我们只让它显示不同的颜色:

1
2
3
4
5
6
7
8
9
.test {
color: red;
}
.test1 {
color: green;
}
.test2 {
color: black;
}

然后定义方法:

1
2
3
4
5
6
7
8
9
10
11
export default {
methods: {
getClass() {
return {
test: false,
test1: false,
test2: true,
}
},
},
}

最后我们在模板中绑定这个方法:

1
2
3
<view :class="getInlineClass">
test
</view>

发现并没有效果。。。。

然后尝试来尝试去,加上括号就可以了:

1
2
3
<view :class="getInlineClass()">
test
</view>

有啥不一样吗?

带括号和不带括号的区别是,不带括号的话函数的参数默认是$event,带括号的话就是自己传递参数,这里也没啥传输的问题。可能是uniapp秀逗了。。。。🤣

得,发布到微信小程序的时候报错了,不支持这种情况。

官网有解释:

为节约性能,我们将Class与Style的表达式通过compiler硬编码到uni-app中。非H5端不支持Vue官方文档:Class与Style绑定中的classObject和styleObject语法。

看来只能用字面量的形式了。首先需要在data中定义数据:

1
2
3
4
5
6
7
8
9
data() {
return {
classObj: {
test: false,
test1: false,
test2: false,
}
}
}

然后在html中使用对象的形式绑定:

1
2
<view :class="{'test': classObj.test, 'test1': classObj.test1, 'test2': classObj.test2}">
</view>

base64格式的图片在微信小程序中不显示的问题

使用image接收后台传递的base64格式的图片:

1
2
3
4
this.$api.getIdentify([]).then(res => {
console.log(res);
this.verifyImg = "data:image/png;base64," + JSON.parse(res).data;
});

发现图片不显示。

为啥?

首先检查从接口中获取到的图片数据是否正确,我是在chrome中运行是显示的,所以接口是没问题的。

那么有一种原因是返回的base64的数据中存在回车换行。我们需要将回车换行替换掉即可。

修改上面的数据获取的地方修改为:

1
this.verifyImg = "data:image/png;base64," + JSON.parse(res).data.replace(/[\r\n]/g, '');

然后运行到小程序开发者工具中,发现是正常显示的,欧了。

码字辛苦,打赏个咖啡☕️可好?💘