Element-plus
1. 按需导入
- 安装element
npm install element-plus --save
pnpm add element-plus
- 按需引入
npm install -D unplugin-vue-components unplugin-auto-import
pnpm add -D unplugin-vue-components unplugin-auto-import
- 修改
vite.config.ts
import AutoImport from 'unplugin-auto-import/vite'
import Components from 'unplugin-vue-components/vite'
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'
plugins: [
vue(),
AutoImport({
resolvers: [ElementPlusResolver()]
}),
Components({
resolvers: [ElementPlusResolver()]
})
],
这里的按需引入的两个插件,并不是只为element服务的,它也可以自动引入其他内容
// 自动导入api
AutoImport({
resolvers: [ElementPlusResolver()],
imports: ['vue', 'pinia', 'vue-router'], // 引入这些文件中的api,以后就不用写import {ref} from 'vue'了
dts: 'src/auto-imports.d.ts', // 生成自动导入的类型声明文件
}),
// 自动导入组件
Components({
resolvers: [ElementPlusResolver()],
dirs: ['src/components', 'src/layout/components'], // 自动导入这些文件夹中定义的组件
}),
至此按需引入element就可以使用了
1. 使用自动导入后Eslint报错
2. 组件上面悬停提示
- 在tsconfig.app.json文件中加入:
"types": ["element-plus/global"]
- 把鼠标悬停在element的标签上就能有提示了,感觉看到提示也没有啥用
2. 按需导入后部分插件不可用的解决办法
- 按需导入后
Element
,使用ElMessage
和Loading
时,屏幕并没有显示,这是因为按需导入时没有导入ElMessage
和Loading
的样式
1. 手动引入样式
- 在
main.ts
中导入Element
的全部样式import 'element-plus/dist/index.css'
,但是这样违背了当初按需导入的初衷 - 只导入
ElMessage
的样式,import 'element-plus/theme-chalk/el-message.css
2. 使用插件自动引入
- 安装插件
vite-plugin-style-import
依赖于consola
pnpm add -D vite-plugin-style-import consola
- 修改vite.config.ts
import { createStyleImportPlugin, ElementPlusResolve } from 'vite-plugin-style-import'
export default defineConfig({
plugins: [
vue(),
createStyleImportPlugin({
// 在nodel-module文件夹中找到element组件的css并引入
resolves: [ElementPlusResolve()],
libs: [
{
libraryName: 'element-plus',
esModule: true,
resolveStyle: (name) => {
return `element-plus//theme-chalk/${name}.css`
}
}
]
})
],
...
})
3. 安装插件(官网的方法)
pnpm add -D unplugin-element-plus
- vite.config.ts
import { defineConfig } from 'vite'
import ElementPlus from 'unplugin-element-plus/vite'
export default defineConfig({
// ...
plugins: [ElementPlus({})],
})
3. 动态菜单实现权限管理
- 服务器返回的真实数据
[
{ // 一级菜单数组
"id": 38,
"name": "系统总览",
"type": 1,
"url": "/main/analysis",
"icon": "el-icon-monitor",
"sort": 1,
"children": [ // 二级菜单数组
{
"id": 39,
"url": "/main/analysis/overview",
"name": "核心技术",
"sort": 106,
"type": 2,
"children": null,
"parentId": 38
},
{
"id": 40,
"url": "/main/analysis/dashboard",
"name": "商品统计",
"sort": 107,
"type": 2,
"children": null,
"parentId": 38
}
]
}
]
- 菜单目录
<template>
<el-menu
active-text-color="#fff"
text-color="#b7bdc3"
background-color="#001529"
>
<!-- 循环遍历一级菜单 -->
<template v-for="item in roleMenu" :key="item.id">
<el-sub-menu :index="item.url">
<template #title>
<!-- 一级菜单的图标 -->
<el-icon>
<component :is="item.icon.split('el-icon-')[1]" />
</el-icon>
<span>{{ item.name }}</span>
</template>
<!-- 循环遍历二级菜单 -->
<template v-for="cItem in item.children" :key="cItem.id">
<el-menu-item :index="cItem.url">{{ cItem.name }}</el-menu-item>
</template>
</el-sub-menu>
</template>
</el-menu>
</div>
</template>
- 注意:
index
中的路径必须以/
开头- 当点击菜单项时会导航到
<el-menu-item>
中index
的路径,并且这个路径是绝对路径,它不会拼接上一级<el-sub-menu :index="item.url">
中index
的路径
- html的解释
active-text-color
:活动菜单项的文本颜色text-color
:菜单的文字颜色background-color
:菜单的背景颜色roleMenu
:服务器返回的菜单数据<component :is="item.icon.split('el-icon-')[1]" />
:服务器返回的图标的字符串为 el-icon-chat-line-round 字符串切割后使用chat-line-round
部分,生成 html 代码<el-icon><chat-line-round></el-icon>
:index="item.id + ''"
:index 的值必须为 string,把 number 变为字符串
- 菜单中的各级
el-menu
:整个菜单,背景色,文字颜色el-sub-menu
: 一级菜单,背景色,激活时颜色(二级菜单激活自动激活一级)el-menu-item
:二级菜单,背景色,鼠标悬停颜色,激活时颜色
// 菜单的style
.el-menu { // 整个菜单
height: 100%;
// --el-menu-border-color: #001529; // menu右边框的颜色设置与底同色也能隐藏这1px的border
border-right: none; // menu有个1px的右边框,设置为空
.el-sub-menu { // 一级菜单,无法点击
.el-menu-item { // 设置二级菜单的样式
padding-left: 60px;
background-color: #0c2135; // 菜单项的背景色
}
.el-menu-item:hover {
background-color: #0a60bd;
color: #fff; // 鼠标悬停时的颜色
}
.el-menu-item.is-active {
background-color: #0a60bd; // 被选中的菜单的背景颜色
}
}
}
- 布局中的左侧aside
.el-aside {
// height: 100%;
background-color: #001529;
// overflow-x: hidden;
// overflow-y: auto;
// text-align: left;
// cursor: pointer;
// transition: width 0.3s linear;
// scrollbar-width: none;
&::-webkit-scrollbar {
display: none; // 最主要的,去除滚动条
}
}
- 效果
4. 下拉菜单在focus时总有个黑框
- 方法1:
.el-tooltip__trigger {
outline: none;
}
- 方法2:
其他方法链接
5. 表单校验
rules: 数据验证
model和prop的值是由与定义的响应式变量名对应
6 <el-image>
使用本地图片
Vue3+TypeScript+Vite如何使用require动态引入类似于图片等静态资源
<el-image :src="url"/>
const url = new URL(
'../images/dataScreen-header-btn-bg-r.png', // 本地图片的路径
import.meta.url,
).href
7. 主题相关
- 设置自定义主题
创建scss文件
@forward "element-plus/theme-chalk/src/common/var.scss" with (
$colors: (
"primary": ("base": #2c82ff),
"success": ("base": #31bf00),
"warning": ("base": #ffad00),
"danger": ("base": #e52f2f),
"info": ("base": #8055ff),
)
);
- 在vite.config中配置
- 预加载scss文件
css: {
preprocessorOptions: {
scss: {
additionalData: `@use "@/assets/css/index.scss" as *;`
}
}
有两种方式可以使scss文件生效
①官网的方法
plugins: [
vue(),
ElementPlus({useSource: true,}),
]
②自动引入中添加
- 这种方法只有在完整引入element时生效
Components({
resolvers: [ElementPlusResolver({importStyle:"sass"})]
// dirs: ['src/components', 'src/layout/components'],
})
8. 面包屑
- 基本通用,保证路由的
meta
中title
属性有值
<template>
<div class="breadcrumb">
<el-breadcrumb separator="/">
<el-breadcrumb-item :to="{ path: '/' }">首页</el-breadcrumb-item>
<template v-for="(item, index) in pathname" :key="index">
<template v-if="item.path != '/' && item.title != ''">
<el-breadcrumb-item :to="{ path: item.path }">{{ item.title }}</el-breadcrumb-item>
</template>
</template>
</el-breadcrumb>
</div>
</template>
<script setup lang="ts">
import { useRoute } from 'vue-router'
import { computed } from 'vue'
const route = useRoute()
const pathname = computed(() => {
return route.matched
.filter((item) => item.meta?.title) // 过滤掉没有title的路由信息
.map((item) => ({
title: item.meta.title || '',
path: item.path,
icon: item.meta?.icon || '',
}))
})
</script>
<style scoped lang="scss">
:deep(.el-breadcrumb) {
font-size: 18px;
}
</style>
9. KeepAlive & Transition
<template>
<div class="content">
<router-view v-slot="{ Component }">
<Transition name="fade" mode="out-in">
<KeepAlive>
<component :is="Component"></component>
</KeepAlive>
</Transition>
</router-view>
<!-- <router-view /> -->
</div>
</template>
<script setup lang="ts"></script>
<style scoped lang="scss">
.fade-enter-active,
.fade-leave-active {
transition: opacity 0.3s ease;
}
.fade-enter-from,
.fade-leave-to {
opacity: 0;
}
</style>