Vue + ts 开发遇到的奇怪问题:删了 A 页面的组件引用,B 页面样式表挂了

如题,就是我遇到的奇怪问题,费了我一天,终于搞清楚了原委,荒诞,可笑,气愤,不知道说什么好。

昨天晚上,突然发现我正在写的一个软件,一个目录树的样式崩坏了......

刚看到,我是震惊的,因为我已经很久没碰这个页面了,为啥就突然崩坏了呢?让我有种摸不着头脑的感觉。一度怀疑是我每天执行 npm upgrade,导入了什么莫名的东西,破坏了 CSS。

困扰一夜,到了第二天终究还是要解决的。这种完全摸不着头脑的 bug,我就问你怎么找??

在毫无思路的情况下,只能用最蠢的法子,二分查找法。先找一个完全不可能有问题的 commit,回滚代码,然后二分查找,直到找到引入问题的 commit。逐行比对定位。我先找了个 11月8日的一个 commit,然后是 11月12日,然后是 11月9日,最后发现是 11月9日引入的问题。(我有个很好的习惯,每天会把自己全天的所有commit,压缩在一个里面进行push,导致我的 history 里每天只有一个 commit,比较好找。)

虽然找到了那次 commit,但是里面涉及到 5 个文件我还是毫无头绪,只能再逐个文件回滚到上一个,来试是哪个文件引入的。git checkout <11月8日> -- /path/to/file.vue,用类似这样的命令,日期换成 commit hash,逐个文件回滚,测试,终于给我找到了引入问题的文件。

然后,荒诞的事情来了。

大概简述一下就是 A 页面引入了一个 el-tree 组件,B 页面也引入了一个 el-tree 组件。然后我把 B 页面的 el-tree 删掉了,换成了 el-table,结果 A 页面的 el-tree 的样式崩裂了!荒谬!死也想不到是这样搞坏掉的。

开始还在 el-table 上动脑子,但是理智告诉我不可能。

其实到这里,已经范围已经很小了,就算一行行傻试,也能试出来是怎么回事。我就不描述了,就专注讲讲,到底怎么回事。

在这个 A 页面里,我写了类似这样的代码:

html 复制代码
<script lang="ts" setup>
import { ElTree } from 'element-ui'
const treeRef = ref<InstanceType<typeof ElTree>>()
</script>
<template>
  <el-tree
    ref="treeRef"
    :data="treeData"
    :props="defaultProps"
    node-key="id"
    show-checkbox
    :checkStrictly="true"
    :defaultCheckedKeys="defaultChecked"
    @nodeClick="onNodeClick"
    @checkChange="onCheckChange"
    @check="onCheck"
  />
</template>

在 B 页面里,因为已经删掉了 el-tree,你可以认为 B 页面是空的。

那么 B 页面怎么影响的 A 页面样式呢?

这就要说明一下项目的一个设定,就是 AutoImport,

ts 复制代码
export default defineConfig({
  base: path.resolve(__dirname, './dist/'),
  plugins: [
    vue(),
    AutoImport({
      resolvers: [ElementPlusResolver()]
    }),
    Components({
      resolvers: [ElementPlusResolver()]
    }),
    ViteYaml(),
  ],
  resolve: {
    alias: {
      '@': fileURLToPath(new URL('./src', import.meta.url))
    }
  }
})

这是一个 vite.config.ts 的节选,可以看到引入了一个 AutoImport 的组件。

因为,此前在 B 页面引用 el-tree 的时候,只是一个简单的原型,所以就是光秃秃放了一个 el-tree 在上面。所以,B 页面激活了 AutoImport 的特性,所以 el-tree 是自动导入到项目的。

而在 A 页面,因为已经写好了很多的逻辑,必须用到 el-tree 的引用,就要定义一个叫 treeRef 的引用变量,又因为好死不死的用了 typescript,所以,定义 treeRef 必须清晰指定类型,才能在后期顺利调用引用上的方法。

而定义类型的时候,AutoImport 特性并没有生效,于是我手动写了一句至关重要的 bug。

ts 复制代码
improt { ElTree } from 'element-ui'

这句话放在页面上,是有副作用的,只导入了 el-tree 的组件而没有导入对应的样式。

在 B 页面引用 el-tree 的时候,会自动在全局导入样式,所以 A 页面看起来正常的,而我删掉 B页面对 el-tree 的引用后,样式也自动去掉了,而 A 页面又没有正确导入 el-tree 的样式,于是,就崩坏了。

等我好不容易知道后,修复起来也简单无比:

ts 复制代码
import type { ElTree } from 'element-ui'

改成这样,就完事了,只有四个按键 type 就修复了。

教训

要说有啥教训,就是我对 vite 一知半解,对 autoimport 一知半解,对 typescript 也一知半解,然后我竟然做项目的时候选了 typescript,当然,其实对前端也一知半解。最后给自己徒增烦恼而已。

记录下来,供大家找乐子!

相关推荐
崔庆才丨静觅6 小时前
hCaptcha 验证码图像识别 API 对接教程
前端
passerby60617 小时前
完成前端时间处理的另一块版图
前端·github·web components
掘了7 小时前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结
崔庆才丨静觅7 小时前
实用免费的 Short URL 短链接 API 对接说明
前端
崔庆才丨静觅7 小时前
5分钟快速搭建 AI 平台并用它赚钱!
前端
崔庆才丨静觅8 小时前
比官方便宜一半以上!Midjourney API 申请及使用
前端
Moment8 小时前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端
崔庆才丨静觅8 小时前
刷屏全网的“nano-banana”API接入指南!0.1元/张量产高清创意图,开发者必藏
前端
剪刀石头布啊8 小时前
jwt介绍
前端
爱敲代码的小鱼8 小时前
AJAX(异步交互的技术来实现从服务端中获取数据):
前端·javascript·ajax