Vue 3 使用 Element Plus 组件自动导入

使用 Vue 3 配合 Element Plus 进行 App 开发是一种很流行的搭配,我也选择了这对组合,此前并不了解前端开发,所以我按照文档进行操作。在全部导入和按需导入里,我选择了感觉会比较精益的按需导入模式。不过,文档在这方面的介绍并不全面。

全部导入

typescript 复制代码
// main.ts
import { createApp } from 'vue'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import App from './App.vue'

const app = createApp(App)

app.use(ElementPlus)
app.mount('#app')

这是官方文档中提供的全部导入的方法。通过这种方法,我们可以安全的在整个项目的所有地方,使用 Element UI 的组件,不用担心引用和样式的问题。后来我才知道,这可能是一种更好的选择,如果你急功近利想要完成项目,这种方法可能是一种问题比较少的方法。

按需导入

按需导入,分为自动导入和手动导入两种,其中手动导入是比较麻烦的,每用到一个组件,都需要手动 import 这个组件用到的代码和样式,非常麻烦,我直接就跳过了没看。选了利用插件支持的自动导入方法,需要额外的插件支持:

shell 复制代码
npm install -D unplugin-vue-components unplugin-auto-import

这也是官方比较推荐的方法,Vite 的配置如下:

typescript 复制代码
// vite.config.ts
import { defineConfig } from 'vite'
import AutoImport from 'unplugin-auto-import/vite'
import Components from 'unplugin-vue-components/vite'
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'

export default defineConfig({
  // ...
  plugins: [
    // ...
    AutoImport({
      resolvers: [ElementPlusResolver()],
    }),
    Components({
      resolvers: [ElementPlusResolver()],
    }),
  ],
})

不得不说,整个开发体验非常好,到这里,多数情况下引用 Element UI 组件,都很方便,直接写代码就行。不过,仍然有一些,每个人都难免遇到的情况,这个文档没有详细介绍,应该怎么处理。

遇到的问题

我们都知道,一个 Vue 组件 SFC,包含三个部分,<template><script><style>,我发现,在实际使用中,一般来说,引用 Element UI的话,我们都会写在这个 <template> 里面。比如:

typescript 复制代码
<template>
  <el-tree />
</template>

在这种情况下,上文提到的自动导入方案,都会很好地工作。但是,有时候,你会发现,你不止会在 <template> 里面使用到组件。比如,我昨天就撰文说了那个奇怪的问题,就是一种情况。

typescript 复制代码
<script lang="ts" setup>
const treeRef = ref<InstanceType<typeof ElTree>>(null)
</script>
<template>
  <el-tree
    ref="treeRef"
   />
</template>

在上面这个代码案例里,我们因为某种原因,需要一个 ElTree 组件的引用,好在代码里操作它,如果你用了 TypeScript 的情况下,如果不声明引用的类型,那么 ElTree 上带有的方法,是不会在 IDE 里提示的,甚至你调用了,还会报错。因为 IDE 提示,不能在 never 类型上使用该方法。虽然说,可能执行的时候是不会有错的,但是你连编译这关可能都过不了。

(所以说,尽量不要选择 TypeScript 除非真的有这个需要,或者跟我一样轴)

但是,这时候我就发现,在 <script> 里出现的 ElTree 的名字,上面提到的自动导入,并不能自动解决。尤其这种在泛型括号里出现的组件名字。解决这种情况方法,昨天的文章我也提及了:

typescript 复制代码
<script lang="ts" setup>
import type { ElTree } from "element-plus"
</script>

注意上面代码里的 type 这四个字母,如果你去掉,也不会报错,那样就是你直接导入组件而不是导入类型。导入组件,是有副作用的,会导致这个页面的 tree 组件样式缺失。具体原理我这会儿还没懂,大体上就是在自动导入的环境下,你如果手动导入了,会出冲突。

另一个案例

除了这个情况,还有一种情况,你会遇到在 <script> 里出现组件的情况,那就是那些默认没有模版,全动态使用的组件,比如 ElMessageBox 和 ElMessage。

typescript 复制代码
<script lang="ts" setup>

function callMsg() {
  ElMessageBox.confirm(
    "一旦执行不可撤销,是否继续?",
    "注意",
    {
      confirmButtonText: "确定",
      cancelButtonText: "取消",
      type: "warning"
    }
  }
}
</script>

上面是一个使用的例子,在这个例子里,一开始介绍的按需自动导入,也不会生效。这种情况,还不同于上一种情况,不是出现在类型泛型的尖括号里,而是出现在代码里,这里导入 type 是不行的。我们需要在 vite 的自动导入配置里加入一个 eslint 有关的配置:

typescript 复制代码
// vite.config.ts
import { defineConfig } from 'vite'
import AutoImport from 'unplugin-auto-import/vite'
import Components from 'unplugin-vue-components/vite'
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'

export default defineConfig({
  // ...
  plugins: [
    // ...
    AutoImport({
      eslintrc: {
        enabled: true
      },
      resolvers: [ElementPlusResolver()],
    }),
    Components({
      resolvers: [ElementPlusResolver()],
    }),
  ],
})

注意 13-15 行,这行配置会导致插件自动生成一个文件 .eslintrc-auto-import.json 这个文件,文件名是可以用参数指定自定义的,就不演示了。这个文件在目录下形成后,还要把这个文件告知给 eslint 才能起作用。

javascript 复制代码
//.eslintrc.cjs
/* eslint-env node */
require('@rushstack/eslint-patch/modern-module-resolution')

module.exports = {
  root: true,
  extends: [
    'plugin:vue/vue3-essential',
    'eslint:recommended',
    '@vue/eslint-config-typescript',
    '@vue/eslint-config-prettier/skip-formatting',
    './.eslintrc-auto-import.json'
  ],
  parserOptions: {
    ecmaVersion: 'latest'
  },
  ignorePatterns: ['main.js', 'preload.js']
}

注意上面的第 12 行,把新自动生成的文件,加入了配置。除了上述文件,根目录下还有生成一个文件 auto-imports.d.ts 文件,还要将这个文件告知给 ts:

json 复制代码
//tsconfig.json
{
  "extends": "@vue/tsconfig/tsconfig.dom.json",
  "include": ["env.d.ts", "src/**/*", "src/**/*.vue", "./auto-imports.d.ts"],
  "exclude": ["src/**/__tests__/*"],
  "compilerOptions": {
    "composite": true,
    "baseUrl": ".",
    "paths": {
      "@/*": ["./src/*"]
    },
    "types": ["@modyfi/vite-plugin-yaml/modules"]
  }
}

注意第 4 行的最后,加入了这个文件,作为一个 include 文件,到此,此种情况就不会再报错了。

结论

这种很重要,而且几乎人人会遇到的情况,官方文档竟然缺失,这让人很遗憾,作为一个小白,我遇到了就是全网到处乱找,而不少文章都是告诉我,遇到了就改成本文第一节提到的方法,改为全量导入。

如果按需导入根本不能解决问题,那么又有什么存在的必要呢?其实我现在还是有点一知半解,为什么我介绍的关于 ElTree 的那种情况,我介绍的这个关于 eslint 和 ts 的配置也解决不了。这些无数人使用的插件都是大漏勺么?随便就漏掉一些很常见的问题的处理。

相关推荐
高兴蛋炒饭1 小时前
RouYi-Vue框架,环境搭建以及使用
前端·javascript·vue.js
ᥬ 小月亮2 小时前
Vue中接入萤石等直播视频(更新中ing)
前端·javascript·vue.js
呜呼~225143 小时前
前后端数据交互
java·vue.js·spring boot·前端框架·intellij-idea·交互·css3
Ares码农人生4 小时前
React 高级组件开发:动态逻辑与性能优化
vue.js·前端框架
嘤嘤怪呆呆狗5 小时前
【开发问题记录】执行 git cz 报require() of ES Module…… 错误
前端·javascript·vue.js·git·vue
ganlanA8 小时前
uniapp+vue 前端防多次点击表单,防误触多次请求方法。
前端·vue.js·uni-app
ZHYCH8 小时前
图片加载失败重试,重试至预期次数使用占位图
前端·vue.js
程序员_三木8 小时前
在 Vue3 项目中安装和配置 Three.js
前端·javascript·vue.js·webgl·three.js
lxw18449125148 小时前
vue 基础学习
前端·vue.js·学习
徐_三岁8 小时前
Vue3 Suspense:处理异步渲染过程
前端·javascript·vue.js