被 UNIAPP 折磨的一天。

2022-01-16 11:51:22 +08:00
 Danswerme

高度

用 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>

CSS 变量

正打算降级,突然发现 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

NVUE

这个 App 里有视频播放的页面,所以用了 UNIAPP 的nvue来开发。首先发现布局全部炸了,分析了一遍之后发现是flex全部从columnrow了。 按照 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下面又正常呢?

Mock 失效

Vue3开发时,我使用了better-mock,一切正常。到了Vue2,Mock 失效了,劫持不到请求。无奈只能在公用的 HTTP 请求工具里动手脚,根据请求 url 手动执行 Mock 返回数据。

import Mock from "better-mock/dist/mock.mp.esm";

无法形容的 BUG

之前使用Vue3开发时,nvue页面如果调用了含有store的 API ,页面就白屏了,猜测是尚未适配Vue3的 store 。于是我把nvue页面用到的几个接口单独import一个文件里并export出去,在App.vue页面里将这几个接口挂载到globalData上供nvue页面使用,在使用Vue3时一切正常。

切换到Vue2之后,store可以正常调用了,也就不用在App.vue里进行中转了。这时候我发现Mock里有几个接口失效了,排查一番后发现Mockapi接口文件里引入的 HTTP 请求路径为undefined

这些 HTTP 请求路径都是const定义的常量字符串,不存在被重写的可能。而且在别的文件里引用都正常,我有些怀疑人生了。 我重启系统并重装了HbuilderX,因为之前也有类似的奇奇怪怪的问题重装HbuilderX之后就正常了。

然而这次并没有生效,我都打算关电脑睡觉了,突然发现Mock引入 HTTP 请求路径之后爆undefinedapi文件都是之前用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`



2157 次点击
所在节点    分享发现
10 条回复
Danswerme
2022-01-16 12:15:31 +08:00
我疯了都,刚想说删了`App.vue`里面引入的文件就好了,现在别的文件又开始爆`undefined`了?你凭啥爆这个啊?

wukongkong
2022-01-16 12:15:35 +08:00
Vue3 开发,不考虑低版本手机吗
Danswerme
2022-01-16 12:20:13 +08:00
@wukongkong 写着玩的,不是公司的,再说了可以用 X5 内核垫底。
uclort
2022-01-16 13:01:57 +08:00
试着降级 hbuilderx 版本,他们的 ide 不同版本也会造成不同的问题。
exploreexe
2022-01-16 15:32:03 +08:00
曾经被折磨过,千万别用 uniapp 搞 APP 折磨自己
EdwinHui
2022-06-25 21:05:46 +08:00
搞不懂,为什么要用 hbuilder 开发来折磨自己呢?用 vscode 不好吗?
Danswerme
2022-06-25 21:07:42 +08:00
@EdwinHui 接手的 UNIAPP 项目只能用 Hbuilder 来编译运行
EdwinHui
2022-06-25 21:20:18 +08:00
@Danswerme 遇到 uniapp 项目我都是转成 cli 模式,用 vscode 上 eslint+prettier ,volar 什么的,就更不用说了。用 eslint 规范代码后,那些莫名其妙的问题就少了很多。暂时用 vue3 开发,仅遇到一个 v-model 会报 undefined 的问题。不过看到这个博客后将它的 emit 改为写在 computed 里就没问题了。
EdwinHui
2022-06-25 21:20:37 +08:00
Danswerme
2022-06-25 21:54:20 +08:00
@EdwinHui 好的非常感谢🙏

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/828534

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX