https://element-plus.org/zh-CN/guide/design.html

设计

  • 控制反馈: 通过界面样式和交互动效让用户可以清晰的感知自己的操作;
  • 页面反馈: 操作后,通过页面元素的变化清晰地展现当前状态。
  • 帮助用户识别: 界面简单直白,让用户快速识别而非回忆,减少用户记忆负担。
  • 用户决策: 根据场景可给予用户操作建议或安全提示,但不能代替用户进行决策;
  • 结果可控: 用户可以自由的进行操作,包括撤销、回退和终止当前操作等。

安装

  • Element Plus 可以在支持 ES2018 和 ResizeObserver 的浏览器上运行。
  • 直接通过浏览器的 HTML 标签导入 Element Plus,然后就可以使用全局变量 ElementPlus
    • 根据不同的 CDN 提供商有不同的引入方式
    • 我们建议使用 CDN 引入 Element Plus 的用户在链接地址上锁定版本,以免将来 Element Plus 升级时受到非兼容性更新的影响。 锁定版本的方法请查看 unpkg.com
<head>
  <!-- Import style -->
  <link rel="stylesheet" href="//unpkg.com/element-plus/dist/index.css" />
  <!-- Import Vue 3 -->
  <script src="//unpkg.com/vue@3"></script>
  <!-- Import component library -->
  <script src="//unpkg.com/element-plus"></script>
</head>

快速开始

  • 如果您使用 Volar,请在 tsconfig.json 中通过 compilerOptions.type 指定全局组件类型。
    • 注释:compilerOptions.type 声明类型应该包括的文件夹
// tsconfig.json
{
  "compilerOptions": {
    // ...
    "types": ["element-plus/global"]
  }
}
  • 按需导入
    • 需要安装unplugin-vue-componentsunplugin-auto-import这两款插件
    • 注释:unplugin-vue-components 是一个用于自动按需引入 Vue 组件的插件,它支持 Vue 2 和 Vue 3,支持 Vite, Webpack, Rspack, Vue CLI, Rollup, esbuild 等构建工具,支持内置的解析器和自定义的解析器,支持 TypeScript 和 .d.ts 文件生成。它可以让您在模板中直接使用组件,而不需要手动导入和注册
    • 注释:unplugin-auto-import 是一个用于自动按需引入 Vue, React, Pinia 等库的 API 的插件,它也支持多种构建工具和 TypeScript
    • 注释:这两个插件都是基于 unplugin 这个框架开发的,unplugin 是一个用于创建通用的构建工具插件的框架
  • 对于 Nuxt 用户,只需要安装 @element-plus/nuxt 即可
// nuxt.config.ts
export default defineNuxtConfig({
  modules: ['@element-plus/nuxt'],
})
  • Element Plus 提供了基于 ES Module 的开箱即用的 Tree Shaking 功能。
    • 需要安装 unplugin-element-plus 来导入样式。
    • 注释:unplugin-vue-components 和 unplugin-element-plus 都能支持按需导入,建议使用 unplugin-element-plus 就行
// vite.config.ts
import { defineConfig } from 'vite'
import ElementPlus from 'unplugin-element-plus/vite'

export default defineConfig({
  // ...
  plugins: [ElementPlus()],
})
  • 引入 ElementPlus 时,可以传入一个包含 size 和 zIndex 属性的全局配置对象。 size 用于设置表单组件的默认尺寸,zIndex 用于设置弹出组件的层级,zIndex 的默认值为 2000。
import { createApp } from 'vue'
import ElementPlus from 'element-plus'
import App from './App.vue'

const app = createApp(App)
app.use(ElementPlus, { size: 'small', zIndex: 3000 })
<template>
  <el-config-provider :size="size" :z-index="zIndex">
    <app />
  </el-config-provider>
</template>

<script>
import { defineComponent } from 'vue'
import { ElConfigProvider } from 'element-plus'

export default defineComponent({
  components: {
    ElConfigProvider,
  },
  setup() {
    return {
      zIndex: 3000,
      size: 'small',
    }
  },
})
</script>

国际化

  • 提供了一个 Vue 组件 ConfigProvider 用于全局配置国际化的设置
<template>
  <el-config-provider :locale="locale">
    <app />
  </el-config-provider>
</template>

<script>
  import { defineComponent } from 'vue'
  import { ElConfigProvider } from 'element-plus'

  import zhCn from 'element-plus/dist/locale/zh-cn.mjs'

  export default defineComponent({
    components: {
      ElConfigProvider,
    },
    setup() {
      return {
        locale: zhCn,
      }
    },
  })
</script>
  • 我们使用 Day.js 库来管理组件的日期和时间,例如 DatePicker。 必须在 Day.js 中设置一个适当的区域,以便使国际化充分发挥作用。 您必须分开导入Day.js的区域设置。
    • 注释:Day.js 对国际化支持良好。但除非手动加载,多国语言默认是不会被打包到工程里的
import 'dayjs/locale/zh-cn'

从 Element UI 升级

  • 迁移
    • 基于类名的 Font Icon 已被移除,这意味着您需要把所有 el-icon- 相关的代码迁移至 SVG Font
    • 全局配置 Vue.prototype.$ELEMENT 已删除
    • 各组件的变量使用 @use 'sass:map'; 进行组织,对应组件的变量移动至对应组件名称下。
// 一个名为$switch的变量,!default表示如果这个变量已经被定义过了
$switch: () !default;
// 使用map.merge函数,把$switch和默认值合并,得到一个新的map,赋值给 $switch
$switch: map.merge(
  (
    'on-color': var(--el-color-primary),
    'off-color': var(--el-border-color-base),
    'core-border-radius': 10px,
    'width': 40px,
    'height': 20px,
    'button-size': 16px,
  ),
  $switch
);

// 用户自定义变量:(将会自动覆盖并合并默认变量)
@forward 'element-plus/theme-chalk/src/common/var.scss' with (
  // 设置主题色
  $colors:
    (
      'primary': (
        'base': green,
      )
    ),
  // 覆盖 switch 组件变量
  $switch: ('height': 40px)
);
  • 部分组件属性修改(略)

主题

  • 注释:全局引入 element-plus 时会独取 package.json 中的 style 这个属性,自动加载它指向的样式文件
  • 在 element-plus scss 文件之前导入element/index.scss以避免 sass 混合变量的问题,因为我们需要通过你的自定义变量生成 light-x。
  • 创建一个 element/index.scss 文件来合并你的变量和 element-plus 的变量。 (如果你在 TypeScript 中导入了它们,他们将不会被合并)
    • 注释:在 ts 中可以直接引用 sass 定义的变量
    • 注释:import './styles/element/index.scss'只引用了变量文件,最后编译为 css 原生变量,覆盖import ElementPlus from 'element-plus'引入样式中定义的 css 原生变量
import { createApp } from 'vue'
import './styles/element/index.scss'
import ElementPlus from 'element-plus'
import App from './App.vue'

const app = createApp(App)
app.use(ElementPlus)
  • 应该将你的 scss 文件与 element 变量的 scss 文件区分开来。 如果将它们混合在一起,element-plus 每次热更新都需要编译大量的 scss 文件,这将会导致编译速度变慢。
  • 如果你正在使用 vite,并且你想在按需导入时自定义主题。
    • 使用 scss.additionalData 来编译所有应用 scss 变量的组件。
import path from 'path'
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
// 你也可以使用 unplugin-vue-components
// import Components from 'unplugin-vue-components/vite'
// import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'

// 或者使用 unplugin-element-plus
import ElementPlus from 'unplugin-element-plus/vite'

// vite.config.ts
export default defineConfig({
  resolve: {
    alias: {
      '~/': `${path.resolve(__dirname, 'src')}/`,
    },
  },
  // css.preprocessorOptions.scss.additionalData 用来指定一些额外的数据,比如变量,函数,混合等,这些数据会被自动添加到每个scss文件的开头,这样就可以在scss文件中直接使用这些数据,而不需要重复地导入或定义它们
  css: {
    preprocessorOptions: {
      scss: {
        additionalData: `@use "~/styles/element/index.scss" as *;`,
      },
    },
  },
  plugins: [
    vue(),
    // use unplugin-vue-components
    // Components({
    //   resolvers: [
    //     ElementPlusResolver({
    //       importStyle: "sass",
    //       // directives: true,
    //       // version: "2.1.5",
    //     }),
    //   ],
    // }),
    // 或者使用 unplugin-element-plus
    ElementPlus({
      // 是否使用element-plus的源码来按需引入组件和样式。
      useSource: true,
    }),
  ],
})
  • 如果你只想自定义一个特定的组件,只需为某些组件单独添加内联样式。
<el-tag style="--el-tag-bg-color: red">Tag</el-tag>
  • 出于性能原因,更加推荐你在类名下添加自定义 css 变量,而不是在全局的 :root 下
.custom-class {
  --el-tag-bg-color: red;
}
  • 通过 js 控制 css 变量

暗黑模式

  • 需要暗色模式,只需在 html 上添加一个名为 dark 的类
// main.ts
// 如果只想导入css变量
import 'element-plus/theme-chalk/dark/css-vars.css'

// html
<html class="dark">
  <head></head>
  <body></body>
</html>
  • 覆盖对应的 css 变量
    • 在 Element Plus 的样式之后导入它
// main.ts
import 'element-plus/theme-chalk/dark/css-vars.css'
import './styles/dark/css-vars.css'

// ./styles/dark/css-vars.css
html.dark {
  /* 自定义深色背景颜色 */
  --el-bg-color: #626aef;
}
  • 也可以导入 scss 文件来实现一样的效果
// styles/element/index.scss
/* 覆盖你需要的变量 */
@forward 'element-plus/theme-chalk/src/dark/var.scss' with (
  $bg-color: (
    'page': #0a0a0a,
    '': #626aef,
    'overlay': #1d1e1f,
  )
);

自定义命名空间

  • Element Plus 提供的默认命名空间为 el。 在特殊情况下,我们需要自定义命名空间
    • 必须同时设置 ElConfigProvider 和 scss $namespace
<!-- App.vue -->
<template>
  <el-config-provider namespace="ep">
    <!-- ... -->
  </el-config-provider>
</template>

// styles/element/index.scss
// we can add this to custom namespace, default is 'el'
@forward 'element-plus/theme-chalk/src/mixins/config.scss' with (
  $namespace: 'ep'
);
// ...

// vite.config.ts
import { defineConfig } from 'vite'
// https://vitejs.dev/config/
export default defineConfig({
  // ...
  css: {
    preprocessorOptions: {
      scss: {
        additionalData: `@use "~/styles/element/index.scss" as *;`,
      },
    },
  },
  // ...
})

SSR

  • 当使用 Element Plus 在 SSR 场景下开发时,您需要在 SSR 期间进行特殊处理,以避免水合错误。
    • 注释:水合是指在服务端渲染(SSR)的过程中,客户端接收到服务端渲染的 HTML 片段后,重新创建组件树并将动态数据注入其中,使得组件树能够响应用户交互的过程
    • 注释:水合错误是指在服务端渲染(SSR)的过程中,服务端渲染的 DOM 结构和浏览器端渲染的 DOM 结构不一致,导致两者无法正确地融合(水合)的错误
  • 提供的值用于生成 ElementPlus 中的唯一ID。 因为不同的 IDs 容易发生SSR中的水合错误, 为了确保服务器端和客户端生成相同的ID, 我们需要将 ID_injection_key 注入到 Vue。
    • 注释:如果没有提供ID_INJECTION_KEY,那么在客户端进行水合的时候,可能会出现两个相同的组件无法区分的问题
// src/main.js (irrelevant code omitted)
import { createApp } from 'vue'
import { ID_INJECTION_KEY } from 'element-plus'
import App from './App.vue'

const app = createApp(App)
app.provide(ID_INJECTION_KEY, {
  prefix: 1024,
  current: 0,
})
  • Teleport 被元素加元件中的多个组件内部使用 (例如) ElDialog, ElDrawer, ElTooltip, ElDropdown, ElSelect, ElDatePicker ...),所以在SSR期间需要特殊处理。
    • 注释:Teleport 传送组件
    • 一个较容易的解决办法是有条件渲染挂载上的 Teleport 。
      • 注释:Teleport 在挂载时才转移 dom 节点,水合时,js创建的 dom 和服务端的 dom 存在这个差别,导致水合错误。
      • 注释:可以在通过 v-if 绑定状态,在挂载后改为 true,保证初始 dom 水合成功后才增加转移的占位 dom
      • 注释:组件 v-if=false 不会触发挂载事件
    • 另一种方式是将传送标记注入到你的 HTML 页面末尾的正确位置。
      • 注释:他们被独立出来了,不会影响主体部分的水合
      • 基于 ElTooltip 的 teleported 的属性应该是一致的,建议使用默认值。
        • 注释:teleported 用来控制是否使用 append-to 属性,append-to默认值是 elemit-plus 添加在 body 下的一个 div,默认类似<div id="el-popper-container-202"></div>,部分元素的文档说明为 body,与事实不符
      • ElDialog 和 ElDrawer 的 append-to-body 属性值应该是一致的,建议启用 append-to-body。
      • ElSubMenu组件有多层弹出窗口,建议启用 popper-append-to-body
    • 您需要注入靠近 <body> 标签的传送标记。(疑问)
<!DOCTYPE html>
<html lang="en">
  <head>
    <title>Element Plus</title>
    <!--preload-links-->
  </head>
  <body>
    <!--app-teleports-->
    <div id="app"><!--app-html--></div>
    <script type="module" src="/src/entry-client.js"></script>
  </body>
</html>
  • 如果您修改了 Namespace 或 append-to 属性,您需要调整 #el-popper-container- 值(

内置过渡动画

  • 淡入淡出 el-fade-in-linear 和 el-fade-in 两种效果
  • 缩放 el-zoom-in-center,el-zoom-in-top 和 el-zoom-in-bottom 三种效果
  • 使用 el-collapse-transition 组件实现折叠展开效果

开发指南

  • 注释:参与 element plus 的开发指南
  • 本地开发指南
    • 注释:gitHub管理方案

开发常见问题

  • 链接本地依赖
    • 注释:在其他项目跳时 element-plus 本地打包后的结果
# 获取构建结果
pnpm build
cd dist/element-plus
# set cur element-plus to global `node_modules`
pnpm link --global
# for esm we also need link element-plus for dist
pnpm link --global element-plus

# 进入你的项目, 链接到 `element-plus`
cd your-project
pnpm link --global element-plus
  • 主题
    • 不应在scss文件中写入中文注释
    • 那将会在 vite 构建下的 css 文件开头生成警告信息 @charset "UTF-8";

提交示例(略)

  • 注释:提交 git 要怎么写 message

翻译(略)

  • 采用了 Crowdin 作为自动化的第一步来升级文档站
    • 注释:Crowdin是一个基于云的本地化管理平台,它可以帮助你的团队高效地管理多语言内容

组件————————————————

Icon 图标

  • 注释:每一个图标都被封装成独立的组件
  • 使用 unplugin-icons 和 unplugin-auto-import 从 iconify 中自动导入任何图标集。
    • 注释:unplugin-icons是一个可以动态生成图标组件的插件。
    • 注释:生成的图标组件可以通过 unplugin-auto-import 自动导入
    • 注释:Iconify 是一个开源的图标项目,它收集了一百多个高质量的图标库,包括 Ant Design、Bootstrap、Feather、Material Design 等。
    • 注释:Iconify 提供了多种方式来引入和使用图标,如 Web Component、React Component、Vue Component 等。
  • 通过添加额外的类名 is-loading,你的图标就可以在 2 秒内旋转 360 度

Config Provider 全局配置

  • i18n 配置
<template>
  <div>
    <el-button mb-2 @click="toggle">Switch Language</el-button>
    <br />

    <el-config-provider :locale="locale">
      <el-table mb-1 :data="[]" />
      <el-pagination :total="100" />
    </el-config-provider>
  </div>
</template>

<script lang="ts" setup>
import { computed, ref } from 'vue'
import zhCn from 'element-plus/dist/locale/zh-cn.mjs'
import en from 'element-plus/dist/locale/en.mjs'

const language = ref('zh-cn')
const locale = computed(() => (language.value === 'zh-cn' ? zhCn : en))

const toggle = () => {
  language.value = language.value === 'zh-cn' ? 'en' : 'zh-cn'
}
</script>
  • 对消息进行配置
    • 疑问:ElMessage 是如何获取正确的组件实例的
<template>
  <div>
    <el-config-provider :message="config">
      <el-button @click="open">OPEN</el-button>
    </el-config-provider>
  </div>
</template>

<script lang="ts" setup>
import { reactive } from 'vue'
import { ElMessage } from 'element-plus'
const config = reactive({
  max: 3,
})
const open = () => {
  ElMessage('This is a message.')
}
</script>
posted on 2023-09-18 11:19  噬蛇之牙  阅读(1057)  评论(0编辑  收藏  举报