用 UNIAPP + Vue3 开发 App ,开发环境下真机和模拟器上一切正常,然而正式打包之后部分安卓手机上scroll-view
高度失效,尝试了各种方法修复无果。
我写了个简单的含有scroll-view
组件的 DEMO ,分别用 Vue2 和 Vue3 的方式打包了一次, 发现使用 Vue2 时没有任何问题,用 Vue3 打包时就出现这个问题了,无奈打算降回 Vue2 。
<view class="full-height flex-column">
<slot name="top" />
<view class="scroll-container" style="flex: 1; position: relative;">
<scroll-view scroll-y class="abs-full">
<slot />
</scroll-view>
</view>
</view>
正打算降级,突然发现 iOS 上切换页面时Tabbar
高度会上下闪烁一下,百思不得其解。最后发现是safe-area-inset-bottom
CSS 变量的问题,页面切换时它的值会突然变为 0 ,加载完成后又变回原来的值,而Tabbar
组件里为了兼容底部安全区,使用了padding-bottom: calc(var(--safe-area-bottom) + 16rpx)
这种方式计算padding
。
page {
--safe-area-bottom: constant(safe-area-inset-bottom);
--safe-area-bottom: env(safe-area-inset-bottom);
}
.tabbar {
padding-bottom: calc(var(--safe-area-bottom) + 16rpx);
}
在 HbuilderX 上个版本里这个 CSS 变量是直接无效为 0 ,当时我是在应用启动时获取了底部安全区的高度,然后把高度写入 style 提供给Tabbar
组件。前几天看官方说修复了,这才几天过去又出了这种幺蛾子问题?官方说修复好的时候我切换回了使用safe-area-inset-bottom
变量的方式,现在又不得不切换回去。
修好页面闪烁的问题,花了一天时间吭哧吭哧的把所有的代码从 Vue3 降级回到了 Vue2 。 切换完之后开始调试,首先是全局组件全部找不到; 我是将所有的全局组件列为一个数组,并使用Vue.component(name, component)
的方式进行加载。
看了一下文档,说是 UNIAPP 为了编译到多平台,使用了静态分析代码,不支持动态加载组件,建议使用他们的easycom
方式进行组件注册。那为什么之前 Vue3 我用这种方式就可以动态加载呢?
好吧,那就使用easycom
进行注册,按照他们的配置要求开启了easycom
,并配置了匹配components
文件夹内组件的正则表达式。配置完成后重新编译,提示我找不到文件@/components/slot/index.vue
,绝了,这是把slot
也当组件给我解析了?得,我手动全部引用一遍吧。
"easycom": {
"autoscan": true,
"custom": {
"(.*)": "@/components/$1/index.vue"
}
}
搜了下,20 年 3 月就有这个问题,现在还没修?https://ask.dcloud.net.cn/question/91597
这个 App 里有视频播放的页面,所以用了 UNIAPP 的nvue
来开发。首先发现布局全部炸了,分析了一遍之后发现是flex
全部从column
变row
了。 按照 UNIAPP 文档的说法,nvue
里所有的元素默认都是flex
元素,且flex
方向默认都是column
。可以在manifest.json
配置文件里修改flex
默认的方向。
之前用 Vue3 写的时候,为了和平时开发保持一致,我在配置文件里设置里默认方向为row
,然而并没有生效。我就按照默认flex-direction: column
的方式来开发了。 切换回 Vue2 之后,这个配置文件又生效了,当然布局就炸了。
修好布局,发现进入nvue
页面后总是提示没有登录。这个项目里 api 请求是封装过的,在请求前会从 store 里检查登录状态并从中获取 token 。console.log
看了一下,只要是nvue
页面调用的 api ,获取 store 里的状态永远是初始值。 看了下文档,哦,nvue
页面不支持直接引入 store 使用,只能用$store
或者辅助函数,这是连引入的api
都影响到了? 行吧,的确是我的锅,没有认真看文档,那为啥Vue3
下面又正常呢?
用Vue3
开发时,我使用了better-mock
,一切正常。到了Vue2
,Mock 失效了,劫持不到请求。无奈只能在公用的 HTTP 请求工具里动手脚,根据请求 url 手动执行 Mock 返回数据。
import Mock from "better-mock/dist/mock.mp.esm";
之前使用Vue3
开发时,nvue
页面如果调用了含有store
的 API ,页面就白屏了,猜测是尚未适配Vue3
的 store 。于是我把nvue
页面用到的几个接口单独import
一个文件里并export
出去,在App.vue
页面里将这几个接口挂载到globalData
上供nvue
页面使用,在使用Vue3
时一切正常。
切换到Vue2
之后,store
可以正常调用了,也就不用在App.vue
里进行中转了。这时候我发现Mock
里有几个接口失效了,排查一番后发现Mock
从api
接口文件里引入的 HTTP 请求路径为undefined
。
这些 HTTP 请求路径都是const
定义的常量字符串,不存在被重写的可能。而且在别的文件里引用都正常,我有些怀疑人生了。 我重启系统并重装了HbuilderX
,因为之前也有类似的奇奇怪怪的问题重装HbuilderX
之后就正常了。
然而这次并没有生效,我都打算关电脑睡觉了,突然发现Mock
引入 HTTP 请求路径之后爆undefined
的api
文件都是之前用Vue3
时在中转文件里曾经引入过的api
文件。可是现在使用了Vue2
之后根本就没用到这个中转文件,只是在App.vue
里引入了一下。
我去App.vue
里注释掉引入后就不爆undefined
了,这是什么魔幻问题???
// api/user.js
import http from "@/utils/http";
export const GET_USERINFO_PATH = "/user/info";
export const getUserInfo = () => http.get(GET_USERINFO_PATH);
// bus/nvue.js
import { getUserInfo } from "@/api/user.js"
export default {
getUserInfo
};
// mock/config.js
import Mock from "better-mock/dist/mock.mp.esm";
import { GET_USERINFO_PATH } from "@/api/user.js"
console.log(GET_USERINFO_PATH);
// 只要`App.vue`里引入上面那个文件,这里就变成`undefined`了,为啥?
// App.vue
import nvue from "@/bus/nvue.js";
// 只要引入了这一行,Mock 里就爆`undefined`
1
Danswerme OP |
2
wukongkong 2022-01-16 12:15:35 +08:00 via Android
Vue3 开发,不考虑低版本手机吗
|
3
Danswerme OP @wukongkong 写着玩的,不是公司的,再说了可以用 X5 内核垫底。
|
4
uclort 2022-01-16 13:01:57 +08:00 via iPhone
试着降级 hbuilderx 版本,他们的 ide 不同版本也会造成不同的问题。
|
5
exploreexe 2022-01-16 15:32:03 +08:00
曾经被折磨过,千万别用 uniapp 搞 APP 折磨自己
|
6
EdwinHui 2022-06-25 21:05:46 +08:00
搞不懂,为什么要用 hbuilder 开发来折磨自己呢?用 vscode 不好吗?
|
8
EdwinHui 2022-06-25 21:20:18 +08:00
@Danswerme 遇到 uniapp 项目我都是转成 cli 模式,用 vscode 上 eslint+prettier ,volar 什么的,就更不用说了。用 eslint 规范代码后,那些莫名其妙的问题就少了很多。暂时用 vue3 开发,仅遇到一个 v-model 会报 undefined 的问题。不过看到这个博客后将它的 emit 改为写在 computed 里就没问题了。
|
9
EdwinHui 2022-06-25 21:20:37 +08:00
|