MIGRATION_RULES.md 7.1 KB

Vue 2 + Element UI → Vue 3 + Element Plus 迁移规则

适用于 pc-v3/src/ 下的 .vue 文件。逐文件应用以下机械转换。

1. 模板(template)转换

1.1 组件改名

  • <el-submenu><el-sub-menu>(开闭标签都要改)

1.2 .sync 修饰符

  • :visible.sync="x"v-model="x"
  • :any-prop.sync="x"v-model:any-prop="x"

1.3 .native 修饰符(Vue 3 已移除)

  • @click.native@click
  • @keyup.enter.native@keyup.enter
  • @submit.native.prevent@submit.prevent
  • 其它一切 .native 全部删除该修饰符

1.4 slot 语法

  • slot-scope="scope" → 改成 <template #default="scope"> 包装(如果原本已在 <template> 上则直接换属性)
  • 子元素上的 slot="header" → 抽出来包成 <template #header>...</template>
  • 子元素上的 slot="reference" → 包成 <template #reference>...</template>
  • 子元素上的 slot="dropdown" → 包成 <template #dropdown>...</template>
  • 子元素上的 slot="prefix" / slot="suffix" / slot="append" / slot="prepend" → 同上

举例:

<!-- 旧 -->
<el-popover ...>
  <div>内容</div>
  <el-button slot="reference">触发</el-button>
</el-popover>

<!-- 新 -->
<el-popover ...>
  <div>内容</div>
  <template #reference>
    <el-button>触发</el-button>
  </template>
</el-popover>
<!-- 旧 -->
<el-table-column>
  <template slot-scope="scope">
    <span>{{ scope.row.name }}</span>
  </template>
</el-table-column>

<!-- 新 -->
<el-table-column>
  <template #default="scope">
    <span>{{ scope.row.name }}</span>
  </template>
</el-table-column>

1.5 尺寸 size

  • size="mini"size="small"
  • size="medium" → 删除该属性(用默认)

1.6 图标(核心规则!)

主入口 main.js 已经把 @element-plus/icons-vue 的所有图标全局注册,所以模板里直接用组件名即可,不需要在每个文件 import

1.6.1 <i class="el-icon-xxx"></i><el-icon><Xxx /></el-icon>

按下表对应替换。原 <i> 标签上的 class(除 el-icon-xxx 外的)、@clickstyle 等属性,全部搬到 <el-icon> 上:

旧 class 新组件名
el-icon-monitor Monitor
el-icon-setting Setting
el-icon-s-tools Tools
el-icon-s-fold Fold
el-icon-s-unfold Expand
el-icon-arrow-down ArrowDown
el-icon-arrow-left ArrowLeft
el-icon-arrow-right ArrowRight
el-icon-user User
el-icon-user-solid UserFilled
el-icon-lock Lock
el-icon-plus Plus
el-icon-edit Edit
el-icon-edit-outline EditPen
el-icon-delete Delete
el-icon-view View
el-icon-check Check
el-icon-close Close
el-icon-circle-close CircleClose
el-icon-circle-plus-outline CirclePlus
el-icon-bank-card CreditCard
el-icon-goods Goods
el-icon-collection-tag CollectionTag
el-icon-copy-document CopyDocument
el-icon-data-board DataBoard
el-icon-document Document
el-icon-document-copy DocumentCopy
el-icon-download Download
el-icon-files Files
el-icon-finished Finished
el-icon-folder-opened FolderOpened
el-icon-info InfoFilled
el-icon-link Link
el-icon-message Message
el-icon-more More
el-icon-notebook-2 Notebook
el-icon-picture Picture
el-icon-picture-outline PictureRounded
el-icon-postcard Postcard
el-icon-present Present
el-icon-question QuestionFilled
el-icon-s-data DataAnalysis
el-icon-s-finance Money
el-icon-s-grid Grid
el-icon-s-order List
el-icon-set-up SetUp
el-icon-sort Sort
el-icon-thumb Pointer
el-icon-upload Upload
el-icon-video-play VideoPlay

举例:

<!-- 旧 -->
<i class="el-icon-plus"></i>
<i class="el-icon-edit" style="color:red" @click="x"></i>

<!-- 新 -->
<el-icon><Plus /></el-icon>
<el-icon style="color:red" @click="x"><Edit /></el-icon>

1.6.2 组件属性形式 icon="el-icon-xxx" / prefix-icon="el-icon-xxx"

#prefix/#suffix 等 slot 替代(保持模板内一致,不需要 import):

<!-- 旧 -->
<el-button type="primary" icon="el-icon-plus">添加</el-button>
<el-input prefix-icon="el-icon-user" v-model="x" />

<!-- 新 -->
<el-button type="primary">
  <el-icon><Plus /></el-icon>添加
</el-button>
<el-input v-model="x">
  <template #prefix><el-icon><User /></el-icon></template>
</el-input>

对于 <el-button type="text" icon="el-icon-more">(按钮内只有图标,无文字)也按上面处理:

<el-button type="text">
  <el-icon><More /></el-icon>
</el-button>

1.7 el-button text 类型

  • type="text" 在 Element Plus 仍然支持但已 deprecated,保持不变(不要主动改成 link,免得动到样式)

2. script 部分转换

2.1 全局消息

  • this.$message(...)this.$message.success/info/warning/error(...)
  • → 顶部加 import { ElMessage } from 'element-plus',调用 ElMessage(...) / ElMessage.success(...)

  • this.$confirm(...)ElMessageBox.confirm(...)

  • this.$alert(...)ElMessageBox.alert(...)

  • this.$prompt(...)ElMessageBox.prompt(...)

  • → 顶部加 import { ElMessageBox } from 'element-plus'

如果同一个文件同时用到 message + messagebox,合并成一个 import:

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

2.2 ref 名称

  • 如果 ref="form" 且 script 里 this.$refs.form.validate(...),建议保留原 ref 名以减少 diff(无需统一改名为 formRef)

2.3 Popover doClose

  • this.$refs.xxx.doClose()this.$refs.xxx.hide()(Element Plus ElPopover 暴露 hide 方法)
  • 如果是数组 ref(:ref="pop-${i}"),Array.isArray(ref) ? ref[0] : ref 写法保留,只把末尾 .doClose() 换成 .hide()

2.4 emit 声明

  • Vue 3 推荐在组件里声明 emits,但为了减少改动,本次不强制要求加,子组件用 this.$emit('update:visible', false) 之类继续工作

2.5 富文本(vue-quill-editor → @vueup/vue-quill)

  • 移除 import { quillEditor } from 'vue-quill-editor',移除 components: { quillEditor }
  • 模板里 <quill-editor v-model="x" :options="..." /><quill-editor v-model:content="x" content-type="html" :options="quillOptions" />
  • QuillEditor 已在 main.js 全局注册(kebab-case:<quill-editor>),不必逐文件 import

3. 其它

  • 顶部 import'element-ui' 全部替换成 'element-plus'
  • 'element-ui/lib/...' 之类的 CSS / 子模块 import 全部删除(main.js 统一处理了)
  • slot= 在 template 标签上的写法(如 <template slot="header">)改成 <template #header>
  • 文件中可能存在 Vue.set / Vue.delete —— 模板里不会有,script 里如有出现,改成直接赋值 / delete obj.key

4. 验证

迁移完成后,对每个文件用以下 grep 自查(应该全部为空):

grep -E '\.sync=|\.native|<el-submenu|</el-submenu|slot=|slot-scope|el-icon-|this\.\$message|this\.\$confirm|this\.\$alert|this\.\$prompt|element-ui|vue-quill-editor|Vue\.set|Vue\.delete|size="mini"|size="medium"|\.doClose\(' <file>