element plus使用问题

820 阅读8分钟

菜鸟使用了 element plus 创建了两个项目,结果一个没一点问题,一个老是有警告,也不知道为什么,就算版本搞成一样的也不行,只能退而求其次,不警告算了,也希望可以帮助使用 element plus 读者!!!

element plus

使用 element plus 自然要使用其最强大的按需引入,全部引入实在是太浪费了!

首先我们按照官网的步骤:

npm install -D unplugin-vue-components unplugin-auto-import

vue.config.js

安装完事之后,就要按照官网里面的来配置vite或者webpack就行,感觉很简单(但是不熟悉打包工具的,可能还是不会,所以列一下)

webpack版

const { defineConfig } = require("@vue/cli-service");

// 按需引入element plus
const AutoImport = require("unplugin-auto-import/webpack");
const Components = require("unplugin-vue-components/webpack");
const { ElementPlusResolver } = require("unplugin-vue-components/resolvers");

const port = 8888;

module.exports = defineConfig({
  publicPath:
    process.env.NODE_ENV === "production"
      ? "./" // 生产环境 --> 一般./就行,但是如果服务器有路径要改为:/pathname/
      : "/", // 开发环境
  transpileDependencies: true,// 将第三方包进行兼容转译,但是vite没有(因为大部分第三方包都自己转译好了,可以删除)
  productionSourceMap: false, // 指定在生产环境下是否生成源代码映射文件
  
  // 按需引入element plus
  configureWebpack: {
    resolve: {
      alias: {
        // 设置路径别名
        components: "@/components",
      },
    },
    plugins: [
      AutoImport({
        resolvers: [ElementPlusResolver()],
      }),
      Components({
        resolvers: [ElementPlusResolver()],
      }),
    ],
  },
  
  devServer: {
    port, // 端口
    proxy: {
      "/Api": {
        target: "http://xxxxx", // API服务器的地址
        changeOrigin: true, // 如果接口跨域,需要进行这个参数配置
        pathRewrite: {
          "^/Api": "",
        },
        // headers 是用来设置请求头的字段,referer 字段用于指定请求的来源地址,即告诉后端服务器这个请求的来源是什么(其实可以不要,像下面一个一样)
        headers: {
          referer: "http://xxxx", // 转发接口
        },
      },
      "/aaa": {
        target: "xxxxx", // API服务器的地址
        ws: true, // 代理websockets,及不仅http请求会被代理,ws也会
        changeOrigin: true,
        pathRewrite: {
          "^/bena": "",
        },
      },
    },
  },
});

这里publicPath的配置倒是一场文学,菜鸟也不是很清楚,反正菜鸟上述的可以满足大部分没有特殊情况的开发者,特别是现在大部分都是 nginx 部署,基本上这一套就行了,具体见

在这里插入图片描述

在这里插入图片描述

vite版

import { fileURLToPath, URL } from 'node:url'

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import AutoImport from 'unplugin-auto-import/vite'
import Components from 'unplugin-vue-components/vite'
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'

// https://vitejs.dev/config/
export default defineConfig(({ command }) => {
  return {
    plugins: [
      vue(),
      AutoImport({
        resolvers: [
          ElementPlusResolver(), // 自动导入图标组件
        ],
      }),
      Components({
        resolvers: [
          ElementPlusResolver()
        ]
      }),
    ],
    resolve: {
      alias: {
        '@': fileURLToPath(new URL('./src', import.meta.url))
      }
    },
    server: {
      host: '0.0.0.0', // 不写这个,vite只有localhost一个本地运行服务
      proxy: {
        '/Api': {
          target: 'http://xxx.xx.xx.xx:17100/',
          changeOrigin: true, // 如果接口跨域,需要进行这个参数配置
          rewrite: (path) => path.replace(/^\/Api/, '') // 如果后端不需要 /Api 前缀,可以使用这个选项去除
        }
      }
    }
  }
})

安装element plus

等你兴高采烈的在页面中写入了el-xxx,准备大干一场时坑就来了,当你去到你写了el-xxx的界面时,其编译的时候就会报错:

Module not found: Error: Can't resolve 'element-plus/es' in Module not found: Error: Can't resolve 'element-plus/es/components/base/style/css' in

这个问题就是你没有安装 element plus 只安装了两个自动导入的插件而已,所以还要执行

npm install element-plus --save

注意

1、使用 ElMessage 报错

如果你在 script 中使用了 ElMessage ,那么eslint 会报错没有引入,但是其实是没问题的,只需要在 ElMessage 之前加上该代码:

// eslint-disable-next-line

注意

自动导入后,如果还是按照

import { ElMessage, ElMessageBox  } from "element-plus"

那么样式方面会有问题,因为样式没有引入,所以不要两个相互交叉使用!

但是图标引入还是要import,不要搞混!!!

更优雅的解决办法

这里就要修改配置文件(element plus icon 的配置也在这里,后续就不再重复了,所以要下载 element plus icon,不然这里不能生成自动导入文件,因为运行不起来),这里菜鸟用vite.config.js来说明,主要是webpack的不太清楚,读者可以评论补充!

import { fileURLToPath, URL } from 'node:url'

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import Icons from 'unplugin-icons/vite'
import IconsResolver from 'unplugin-icons/resolver'
import AutoImport from 'unplugin-auto-import/vite'
import Components from 'unplugin-vue-components/vite'
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [
    vue(),
    AutoImport({
      // 解决 ElMessage 报错问题,有时候编译器反应不过来,但是没问题,重启编译器就行
      eslintrc: {
        enabled: true
      },
      resolvers: [
        ElementPlusResolver(), // 自动导入图标组件
        IconsResolver({
          prefix: 'Icon'
        })
      ],
      // 自动导入后面这些包里面的东西,避免每次都要导入router、ref等,有时候编译器反应不过来,但是没问题,重启编译器就行
      imports: ['vue', 'vue-router', '@vueuse/core']
    }),
    Components({
      resolvers: [
        // 自动注册图标组件 --> 自动导入的图标要使用i-ep-xxx/i-ep-xxx-xxx
        IconsResolver({
          enabledCollections: ['ep']
        }),
        ElementPlusResolver()
      ]
    }),
    Icons({
      autoInstall: true
    })
  ],
  resolve: {
    alias: {
      '@': fileURLToPath(new URL('./src', import.meta.url))
    }
  },
  server: {
    host: '0.0.0.0', // 允许内网访问
    // port: "" // 端口
  }
})

但是这个时候,eslint 还是会提示没有引入,这里需要对eslint也进行配置

eslint.config.js(不行)

image.png

注意

这里会有一个问题,就是assert会报错:Parsing error: Unexpected token assert,其实不影响什么,但是非要改,就得把js文件改成cjs文件,原因是: image.png

eslint.config.cjs

image.png

.eslintrc.cjs

image.png

2、有时候会报错 not a function

AutoImport is not a function
    at Object.<anonymous> (F:\pro\plantweb\vue.config.js:40:7)
    at Module._compile (node:internal/modules/cjs/loader:1198:14)
    at Object.Module._extensions..js (node:internal/modules/cjs/loader:1252:10)
    at Module.load (node:internal/modules/cjs/loader:1076:32)

Components is not a function
    at Object.<anonymous> (F:\pro\plantweb\vue.config.js:43:7)
    at Module._compile (node:internal/modules/cjs/loader:1198:14)
    at Object.Module._extensions..js (node:internal/modules/cjs/loader:1252:10)
    at Module.load (node:internal/modules/cjs/loader:1076:32)

这个时候就要降低版本,具体参考:vue 3.0 使用element-plus按需导入方法和报错解决

3、 element plus 版本过高

有的时候 element plus 版本高了也会报错,菜鸟没遇见,读者可以见:vue3引入element-plus报错解决方案

4、警告Feature flag VUE_PROD_HYDRATION_MISMATCH_DETAILS is not explicitly defined.

vue.config.js 添加上该代码:

chainWebpack: (config) => {
  config.plugin("define").tap((definitions) => {
    Object.assign(definitions[0], {
      __VUE_PROD_HYDRATION_MISMATCH_DETAILS__: "false",
    });
    return definitions;
  });
},

参考:Vue3.4+报Feature flag VUE_PROD_HYDRATION_MISMATCH_DETAILS is not explicitly defined... 处理

5、报错 ResizeObserver loop completed with undelivered notifications.

需要在app.vue中加入该代码:

const _ResizeObserver = window.ResizeObserver;
window.ResizeObserver = class ResizeObserver extends _ResizeObserver {
  constructor(callback) {
    callback = debounce(callback, 100); // 防抖函数自己写
    super(callback);
  }
};

参考:关于用element-ui中碰到的ERROR ResizeObserver loop completed with undelivered notifications.问题

防抖函数参考:vue3常用代码

element plus icon

使用 element plus icon 就和使用其他组件是一样的,唯一的区别就是要引入

import { } from "@element-plus/icons-vue";

具体引入什么就是去官网点击图标,将复制下来的引入就行!

注意:

上面 npm 了 element-plus,那么这里的图标可以直接引用,不需要 npm 图标库了!

还有一个坑的地方就是按需引入,但是菜鸟发现按需引入确实可以,但是使用的是时候就不能是官网复制下来的,而是不知道哪里复制的,所以暂时不推荐使用!

按需引用参考:

  1. Element Plus Icon图标自动引入
  2. Vue3!ElementPlus!更加优雅的使用Icon

按需引用

菜鸟在后续使用中还是使用了按需引入,但是其实并不好用!!!

虽然知道了配置(就上面的 更优雅的解决办法 里面提供了),而且知道使用就是把icon的名字改成i-ep-iconname / i-ep-iconname-iconname(两个单词组成的就要变成这样)

但是如果要在el-button里面这样使用

<el-button type="primary" :icon="Search" @click="search">搜索</el-button>

只能引入,无法使用i-eq

element plus 按需导入设置为中文

菜鸟在开发过程中,发现这些 element plus 组件全部默认都是英文,虽然很简单,改不改都无所谓,但是还是要想想怎么解决!

只需要在app.vue中加入这么一行代码就行:

<template>
  <el-config-provider :locale="zhCn">
    <router-view />
  </el-config-provider>
</template>

<script setup>
// 引入element plus中文包
import zhCn from "element-plus/lib/locale/lang/zh-cn";
</script>

已经修复了?

后续的问题,菜鸟没遇见了,估计是被修复了还是怎么样,所以可以止步了!当然如果你真的遇见了,也可以继续看,并留言是什么情况才会遇见!

element plus 和 px2rem 不兼容

如果你在 element plus 项目中引入了 px2rem,那么你可能喜提巨大的图标等!

解决巨大的图标

解决办法就是在既有 px2rem 又有用到 ElMessage 的界面上加上如下代码:

.el-message-icon--error {
  font-size: 5px;
}
.el-message-icon--success {
  font-size: 5px;
}
.el-message-icon--info {
  font-size: 5px;
}

记住不要在 style 上加 scoped !!!

element plus错位的图标

这里是 element plus 自己的bug!

el-message

el-message 的关闭按钮可能会偏移,解决办法就是在 public 底下的 index.html 中加入:

/* 解决 element plus 样式问题 */
.el-icon.el-message__closeBtn {
  position: absolute !important;
}

主要产生原因就是 .el-icon 的样式和 .el-message-closeBtn 样式冲突了,如图:

在这里插入图片描述

el-input / el-select

el-input / el-select 里面的图标可能会偏移,解决办法就是在使用的地方加上 css

.searchBox {
  :deep(.el-input__prefix-inner) {
    align-items: center;
  }
  :deep(.el-input__suffix-inner) {
    align-items: center;
  }
}

这里菜鸟发现 el-date-picker 等 也有类似问题,而且并不是覆盖的原因,也不知道为什么 github 上没人提出来!!!

现在好像没有这个问题了,最近菜鸟的项目没有出现,也不知道是不是px2rem搞的,反正记录一下!!!