lanhu-code-2-el-vue

将静态 Vue 页面(index.vue)改造为动态页面(Custom.vue);执行前必须先应用 ui-ux-max-pro 做 UI/UX 分析;稿源仅限 index.vue、其引用的 CSS 与资源路径,禁止参考仓库内其他文件。Invoke when user wants to transform a static Vue page into a dynamic data-driven page with Element UI components.

Safety Notice

This listing is from the official public ClawHub registry. Review SKILL.md and referenced scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "lanhu-code-2-el-vue" with this command: npx skills add 781818761/lanhu-code-2-el-vue

lanhu-code-2-el-vue

介绍

本 Skill 用于将静态 HTML 页面改造为 Vue 2 + Element UI 的数据驱动动态页面,执行时会直接生成 Custom.vue 文件。

前置 Skill:ui-ux-max-pro

当本 Skill 被触发时,必须先执行 ui-ux-max-pro,再继续执行当前 Skill:

  1. 先读取并遵守 ui-ux-max-proSKILL.md
  2. 先完成 ui-ux-max-pro 要求的 UI/UX 分析、布局判断、视觉一致性检查与可用性评估。
  3. ui-ux-max-pro 的结论作为后续静态页改动态页的设计约束,但不得违反本 Skill 的「唯一信息源」限制。
  4. 然后再继续执行当前 lanhu-code-2-el-vueindex.vueCustom.vue 改造流程。
  5. 若找不到 ui-ux-max-pro,必须告知用户并暂停,不得直接开始生成或改写 Custom.vue

When to Use This Skill

在以下场景触发本 Skill:

  • 用户要求「静态改动态」「把 index.vue 改成 Custom.vue」「按改造规范改造页面」
  • 将某视图文件夹下的静态页面改为 Vue 2 + Element UI 动态页面
  • 需要循环渲染、Element UI 替换、统一 class 命名、像素级还原设计稿

不适用: 全新页面从零开发、非 Vue 2/Element UI 技术栈、不涉及「静态→动态」改造。


执行指令(核心)

当本 Skill 被触发时,必须按照以下步骤直接执行代码改造,生成 Custom.vue 文件,而不是仅提供指导文档。

唯一信息源(生成 Custom.vue 时必须遵守)

生成/改写 Custom.vue 时,只允许使用以下材料作为页面结构与样式的依据:

  1. src/views/${folderName}/index.vue 的源码(模板、脚本、内联样式)。
  2. 由 index.vue 直接或间接引用的样式文件(例如 <style src="./assets/index.css">@importimport 等,按路径相对 index.vue 解析;若存在链式 @import,仅沿该链读取,不得扩大范围)。
  3. 在上述 Vue/CSS 中出现的图片等资源路径(保留或转换为 Custom.vue 所需写法即可;无需读取图片二进制内容作「设计参考」)。

禁止:

  • 不得为拼页面而读取、对照或照搬本仓库其他文件的内容,包括但不限于:同目录或其他视图下的 Custom.vueindex.vue(非当前 ${folderName})、公共组件源码、create.md路由配置package.json 等。
  • 不得以「已有某页的 Custom.vue 写法」为模板生成当前页;每一页只认当前文件夹的 index.vue + 其引用 CSS + 资源路径。

路由配置的例外(仅交付阶段):Custom.vue 已写入磁盘之后允许打开项目路由文件(如 src/router/index.js仅用于登记或校验 index.vue / Custom.vue 的访问路径,使页面可通过 URL 打开。禁止把路由里其它页面的 path/name/meta 当作当前页的 UI 稿源或布局依据。详见 data/router-sync.md 第 5 节。

说明: 本 Skill 正文与 data/ 下的规范文档属于操作规则(如何命名、如何用 Element UI 等),不是「页面稿源」。页面稿源仍仅限上述 1~3 项。

步骤 1: 获取目标文件夹名称

从用户输入中提取 ${folderName}(如:kz、shushi 等)。

步骤 2: 验证源文件存在性(必须执行)

// 必须存在:
必须存在: src/views/${folderName}/index.vue

// 样式文件:以 index.vue 实际引用为准(常见为 ./assets/index.css,若引用多个则均需存在)
// 读取 index.vue 后解析其 style src / @import / import 路径并逐一验证存在

// 目标文件(将被创建或覆盖):
目标文件: src/views/${folderName}/Custom.vue

⚠️ 重要:index.vue 不存在,或其所引用的样式文件缺失,必须告知用户并停止执行。验证通过后,仅读取 index.vue 与这些被引用的样式文件(及链式 @import),不打开其他工程文件。

步骤 3: 读取源文件(仅限唯一信息源)

  1. 使用 Read 工具读取 src/views/${folderName}/index.vue
  2. 根据 index.vue 中的引用,读取其指向的 CSS(及该 CSS 内 @import 的下一层样式,若需要完整样式表)。
  3. 不要读取 package.json路由文件、其他视图的 Custom.vue 等作为模板/稿源/样式依据(见上文「唯一信息源」;路由仅在步骤 8 用于登记,见 data/router-sync.md)。

步骤 4: 分析源文件结构

分析内容:

  1. 识别页面布局 - 确定是单栏、双栏还是多栏布局
  2. 识别重复结构 - 找出需要循环渲染的部分(使用 v-for)
  3. 识别交互元素 - 找出按钮、输入框、多选、单选等可替换为 Element UI 的元素(开关保留原生 DOM,不替换为 el-switch)
  4. 识别样式特征 - 记录关键样式值(颜色、尺寸、间距)
  5. 识别伪控件(必做) - 源页面常用 div+文案+图标模拟表单控件,须按「6.3.4 伪控件识别与替换」规则识别并替换为 el-select、el-checkbox、el-input;取色须按 点击后展开的下拉面板的形态(图1 / 图2) 选用 el-color-picker-extendel-color-picker不以触发区单独判断;见 6.3 映射表6.3.11data/el-color-picker-extend.md §「颜色选择:触发与下拉的共同结构」),避免漏改或错用组件。

步骤 5: 生成 Custom.vue 文件

⚠️ 必须使用 Write 工具直接生成文件,而不是返回代码给用户!

生成的 Custom.vue 必须包含以下结构:

<template>
  <div class="[folderName]_page_container">
    <!-- 改造后的动态页面内容 -->
    <!-- 1. 将重复结构改为 v-for 循环渲染 -->
    <!-- 2. 将原生的 input、button、checkbox、radio 等替换为 Element UI 组件(开关不替换,保留原生结构) -->
    <!-- 3. 保留所有样式,确保像素级一致 -->
  </div>
</template>

<script>
export default {
  name: '[FolderName]Custom',
  data() {
    return {
      // 所有 template 中使用的数据必须在此定义
      // 包括:列表数据、表单数据、状态变量等
    }
  },
  methods: {
    // 所有 @click、@change 等事件处理方法必须在此实现
    // 命名规范:handle + 功能名(如 handleSearch、handleSubmit)
  }
}
</script>

<style scoped>
/* 所有样式必须在此定义,禁止引用外部 index.css */
/* 使用 scoped 避免样式污染 */
/* 对 Element UI 组件使用 ::v-deep 进行样式覆盖 */
</style>

步骤 6: 改造规范(必须遵守)

6.1 文件操作规范

规则说明
❌ 禁止修改源文件index.vue 及其引用的样式文件只能读取,绝对不能修改
✅ 只操作目标文件所有代码只写入 Custom.vue
✅ 唯一稿源结构与样式依据仅限当前 index.vue + 其引用 CSS + 资源路径;禁止参考其他视图/其他 Custom.vue/路由等工程文件生成页面内容
✅ 使用 scoped 样式所有样式必须在 <style scoped> 中定义
✅ 完整单文件组件Custom.vue 必须包含 template、script、style 三部分

6.2 命名规范

  • Class 名仅使用下划线 _ 连接不得包含任何数字(0-9)
  • 序位、顺序用英文词表示(如 firstsecondleftright
  • 命名公式:[folderName]_[功能]_[内容]_[特征]
✅ 正确示例:
kz_header_container
kz_list_item
kz_button_primary
kz_math_cell_first

❌ 错误示例:
group_1              // 含数字
kz_cell_2            // 含数字
box-1                // 使用连字符
headerBox            // 使用驼峰

6.3 Element UI 替换要求

凡有按钮、多选、单选、输入、分页、弹窗等,须替换为 Element UI 组件。不替换:开关保留源页面原生 DOM(如 div + @click、原生 input 等),不使用 el-switch

替换映射表:

原元素Element UI 组件说明
按钮el-button可点击按钮须绑定 @click,并在 methods 中实现对应方法
多选el-checkbox-group + el-checkbox
单选el-radio-group + el-radio互斥多选一;样式与源页一致,激活态与选中项须为主题色,见「6.3.10 单选框识别与主题色规范」
输入框(单行)el-input带外框的搜索框须同时满足「6.3.1 带外框搜索框样式规范」
多行文本el-input type="textarea"可配 show-word-limit、maxlength
下拉选择el-select + el-option
分页el-pagination需定义 currentPage、pageSize、total,实现 size-change、current-change;替换时必须删除原始分页全部静态内容(共 xxx 条、静态页码、上下页、条数/页等),仅保留一个 el-pagination,见「6.3.9 分页替换与主题色规范」
弹窗el-dialog需定义 dialogVisible,实现关闭/确定/取消方法
日期输入el-date-picker
下拉菜单el-dropdown + el-dropdown-menu需实现 @command 处理方法
进度条el-progress
评分el-rate星星颜色、评分数值须与源页面一致,见「6.3.2 el-rate 注意事项」
取色 / 填充(展开后的下拉图1:预设色块矩阵 + Hex/RGB/不透明度 +「最近使用」+ 吸管等;或页内静态整区模拟该形态)el-color-picker-extend触发区长什么样不决定选型,见 data/el-color-picker-extend.md §「颜色选择:触发与下拉的共同结构」;全局注册见 main.js
取色(展开后的下拉图2:Element 默认面板SV 面 + 右侧竖向色相条 + 底部 Hex +「清空」「确定」el-color-picker常见触发器为 字体颜色(A+下划线+箭头)→ 透明叠层删除页内重复取色区6.3.11;细则见 data/el-color-picker-extend.md

替换时必须:

  1. 先删除该区域原有 DOM 结构(含该控件的全部相关 DOM,见下方「下拉框」说明)
  2. 再写入 Element UI 组件
  3. 同时完成 template、data()、methods 三部分(禁止只写 template 不写 methods/data)
  4. ::v-deep 覆盖 Element UI 默认样式,保持视觉一致
  5. 可点击按钮:页面中所有可点击区域(上传、预览、确定、取消、智能合成等)须在 template 中绑定 @click="handleXxx",并在 methods 中实现 handleXxx,命名建议 handle + 功能名(如 handleUploadImage、handleDialogConfirm)

下拉框替换时须删除的 DOM(通用规则): 除「当前选中项 + 箭头」的触发区外,若 index.vue 中还有独立的下拉选项列表(如浮层、侧边列表、鼓点-1~鼓点-11 等静态列表),须一并删除。替换为 el-select 后,选项由 el-select 自带的 dropdown 展示,不得保留原静态选项列表 DOM,否则会出现「识别了下拉框但页面上仍有两套选项」的问题。

6.3.1 带外框的搜索框(el-input)样式规范

当搜索框被包在带边框、圆角的白底容器内(如「搜索资源标题、ID」「搜索你想要的单词」)时,须满足:

  • 外层容器:固定高度(如 48px)、宽度(如 688px)、圆角、边框(须设 border,如 1px solid)、背景色;display: flexalign-items: centerbox-sizing: border-boxoverflow: hidden,使内部输入框垂直居中且不撑高。容器在 hover 与 focus-within 时边框须为主题色.xxx_search_wrapper:hover.xxx_search_wrapper:focus-withinborder-color 为页面主题色),详见 data/recognition-and-fix.md 9.8。
  • .el-input-group:通过 ::v-deep.el-input-group 做样式覆盖:display: flexflex: 1height: 100%min-width: 0border: nonebackground: transparent,避免出现双重边框或额外外框。
  • .el-input / .el-input__inner.el-input 在容器内 height: 100%flex: 1.el-input__inner 去掉自带边框(border: none)、背景透明、高度略小于容器约 2px(如容器 48px 则 inner 约 46px)、line-height 与高度一致、border-radius 仅左侧与容器一致(若右侧为 append 按钮则设为 12px 0 0 12px)、box-sizing: border-boxpadding-left 为前缀图标留足空间(如 44px),避免双边框与错位。
  • 占位符::v-deep .el-input__inner::placeholder 设置 placeholder 颜色与设计稿一致(如 rgba(153, 153, 153, 1))。
  • 前缀图标.el-input__prefix 使用 display: flexalign-items: centerheight: 100%left 与设计一致(如 16px);自定义 prefix 插槽根节点用 display: inline-flexalign-items: center,图标尺寸与设计一致(如 16×16px)。
  • 命名:类名使用 [folderName]_search_wrapper[folderName]_search_input 等规范命名。同一项目内所有带外框的搜索框均按此规则实现。

自检:容器高度与设计一致;容器有 border,hover 与 focus-within 时边框为主题色(见 9.8);无双重边框;.el-input-group 已覆盖无边框且 flex 占满;前缀图标与文字垂直对齐;placeholder 颜色正确;无错位或溢出。

6.3.1.1 placeholder 垂直居中与页面溢出(必做)

  • placeholder 垂直居中.el-input__inner 高度与容器一致(或略小 1~2px),line-height 与高度一致,上下 padding 为 0;.el-input.el-input-groupdisplay: flexalign-items: center,使输入区在容器内垂直居中;必要时对 ::v-deep .el-input__inner::placeholder 设相同 line-height。
  • 输入框/按钮不溢出页面:页面根容器设 overflow-x: hidden;主卡片、Tab 行、底栏、列表区使用 width: 100% + max-width: [设计稿宽度] + min-width: 0 + box-sizing: border-box;带外框搜索框容器在 flex 中设 flex: 1min-width: 0max-width: [设计稿宽度];底栏中间文案将固定大 margin-left 改为 margin-left: auto,避免窄屏下溢出。

详见 data/search-input-and-page-overflow.md(识别步骤、修复方法、需求文案与自检清单)。

6.3.2 el-rate 评分组件注意事项

  • 星星颜色:选中/未选中颜色须与源页面一致(打开 index.vue 查看),不可默认用橙色而源页为黄色。
  • 评分数值:每个维度显示的实心星数须与源页面一致(如色彩 5 星、构图 5 星、想象力 3 星),不得全部默认 5 星或 3 星。
  • 文字样式:「超赞」等评分文字的颜色、大小、位置须与源页面一致,用开发者工具对比。
  • 样式覆盖:星星、文字、间距等均通过 ::v-deep 精确匹配源样式。

6.3.4 伪控件识别与替换(下拉框、多选框、单选框、搜索框)

源页面常使用 div + 文案 + 图标模拟表单控件,没有原生 <select><input type="checkbox"><input type="radio"> 或带外框的 <input type="text">,改造时容易漏识别。须按以下规则识别并替换:

控件类型识别特征(index.vue / index.css)替换为说明
下拉框 select小容器内为「当前选中文案 + 右侧下拉箭头图标」、或「标签 + 可切换项」;样式为带边框、圆角的盒子(如 66×28px)el-select + el-option在 data 中定义选中值(如 selectedXxx),options 与同页列表/配置一致
多选框 checkbox左侧为勾选图标容器(含勾/未勾图或方框)+ 右侧说明文案(如「全选所有模块」「当前配置应用于所有页面」);多行结构相同el-checkbox每项对应 data 中一个布尔(如 checkedAllModules、applyToAllPages)
纵向模块勾选列易漏识别:左侧仅为 ~16×16 方框切图image-wrapper + img),「全选」类长说明;右侧或邻列为模块名(音标、释义、例句、词组等);多行纵向对齐成列;或左侧 flex-col 堆叠多个方框与右侧多行标题行对行对应el-checkbox(无内联文案时隐藏 label)+ 右侧内容区 v-show/v-if 联动data 中用对象(如 moduleFlags)或多项布尔;禁止保留静态勾图;样式见 6.3.4.1data/recognition-and-fix.md §2.2.1、§3.2.1
横向工具条 / 尾行模块勾选易漏识别:在横向 flex-row 中,模块标题(如英式音标、鼓点音频)左侧仍有 16×16 方框切图;或底部 「单词书写」 等行「左方框 + 标签 + 右侧预览」— 与纵列勾选同类语义,只是排在横排/尾行el-checkbox + 对 IPA 区、鼓点 el-select 与图标、书写预览等 v-show 联动须纳入 「全选所有模块」 的同一批布尔;禁止纵列用组件、横条仍留 png;尺寸6.3.4.3recognition-and-fix.md §2.2.2~§2.2.3、§3.2.2~§3.2.3
单选框 radio多个选项中仅能选一项(互斥);圆点/圆圈 + 文案,或 div 模拟的选项组;有「选中」与「未选中」两种视觉状态el-radio-group + el-radio在 data 中定义选中值(如 radioValue),样式与源页一致,选中/悬停为主题色,见 6.3.10
带外框搜索框外层为白底/圆角/边框容器,内为「搜索图标 + 占位文字 + 右侧搜索/按钮」el-input + prefix/suffix 插槽必须同时满足「6.3.1 带外框搜索框样式规范」
取色 / 填充面板(图1 形态)展开后的面板含:标题「填充」等 + 色块格矩阵渐变/透明度滑条#+hex% 不透明RGB 数字格最近使用等(页内整区或弹层);触发区可为按钮或小入口el-color-picker-extenddata/el-color-picker-extend.md §「颜色选择:触发与下拉的共同结构」、§选型、§产品需求
取色(图2 形态)展开后SV 渐变方 + 竖向彩虹色相条 + 底栏 Hex +「清空」「确定」(Element UI 2 默认取色下拉);触发区常为 A+下划线+箭头el-color-picker6.3.11data/el-color-picker-extend.md §对照清单、字体颜色触发器

识别步骤(通用):

  1. 在 index.vue 中搜索:带「选」「勾」「搜索」等语义的文案,或带下拉箭头、勾选图标的 div 结构。
  2. 在 index.css 中确认该区域样式:是否有边框、圆角、固定宽高(如 66×28、16×16 勾选区域)。
  3. 若符合上表特征,在 Custom.vue 中替换为对应 Element UI 组件,并补全 data、methods。
  4. 纵向模块勾选列(补充):在配置/预览区搜索多行「左列小方框图 + 右列模块标题」;若左列无说明性长文案、仅方框 png,须按上表「纵向模块勾选列」处理,详见 data/recognition-and-fix.md §2.2.1
  5. 横向工具条 / 尾行(补充):除纵列外,扫描配置区所有横向行底部尾行:是否存在「方框切图 + 模块名 + 业务区」;若 img 与纵列勾选同资源或同类,须同样改为 el-checkbox,详见 6.3.4.2data/recognition-and-fix.md §2.2.2

6.3.4.1 纵向模块勾选列(无内联文案的 el-checkbox)

  • 结构:保留原 image-wrapper 父级 class 与布局,内部替换为 el-checkbox;模块标题仍为旁侧 span不要把标题塞进 el-checkbox 默认插槽(除非稿面即为一体标签)。
  • 隐藏 label::v-deep .el-checkbox__label { display: none; width: 0; padding: 0; margin: 0; overflow: hidden; },避免 Element 为空白 label 留出间距导致与稿面不齐。
  • 尺寸与视觉::v-deep .el-checkbox__inner 的宽高须与 index.css 中负责方框视觉的一层一致(见 6.3.4.3);border-radius 与稿一致;未选中边框浅灰,选中为白底 + 主题色边框与勾(与稿一致即可);hoveris-focus 边框建议主题色,与 6.3.8 一致。
  • 联动:每个布尔对应右侧一块内容 v-show;双勾(例句/译文)对应同一卡片内两个内容区的分别显示与中隔线条件显示。
  • 禁止:保留原方框 png 冒充勾选态;仅改「全选」行而漏改纵向模块列。

6.3.4.2 横向工具条 / 尾行上的模块勾选与尺寸统一

  • 识别:在顶部横向配置行(如英式音标、鼓点音频)或底部尾行(如单词书写)中,模块标题 span 之前image-wrapper + 小 png,若与左侧纵列模块勾选**尺寸同级(约 16×16)**且语义为「是否展示该段能力」,即属模块勾选,不得仅替换纵列而保留此处静态图。
  • 替换:删除切图,在原 wrapper 内放入与纵列同一 classel-checkbox(如 [folderName]_module_checkbox),保证全页共用同一套 ::v-deep 规则。
  • 联动:英式音标应对 IPA + 播放图标所在行 v-show;鼓点音频若左侧方框表示模块总开关,应对 el-select 及同组图标 v-show;单词书写应对右侧预览词 v-show
  • 全选handleSelectAll / 同步 selectAll 的 keys 须包含上述布尔,与纵列模块字段合并为一套,避免逻辑分裂。
  • 尺寸与勾形(与 6.3.8 配合):全页无文案模块勾选须 class 统一;覆盖 .el-checkbox.el-checkbox__input.el-checkbox__inner.el-checkbox__inner::after 及选中态勾线色;inner 像素须按 6.3.4.3 从 index.css 读取,禁止默认臆断为 16×16。详见 data/recognition-and-fix.md §3.2.2、§3.2.3

需求文案(摘要)

  • 配置区内凡「左方框 + 模块名」式开关,无论出现在纵列、横条还是尾行,均须 el-checkbox,禁止 png 与组件混用。
  • 同一自定义 class + 完整深度样式(含 ::after)方框边长以 index.css 实测为准(常为外层槽位 16px + 内层切图 13px),「全选」须覆盖横条与尾行布尔。

6.3.4.3 多选框原始尺寸识别(wrapper / thumbnail 分层,必做)

稿面常见结构为:外层 image-wrapper_*(或 group_* / box_*)提供 16×16 对齐槽位,内层 thumbnail_*img 为 13×13 且带 margin: 2px 0 0 2px——可见方框的物理像素往往等于 thumbnail 的 width/height,而非外层 wrapper 的 width/height。若将 el-checkbox__inner 一律写成 16×16,会较稿面偏大,与仍使用切图的行或设计稿对比时产生偏差。

识别步骤(须自 index.css / 稿源读取,禁止猜默认):

  1. 在 index.vue 中定位该勾选左侧的 image-wrapper_* + img.thumbnail_*(或仅带 background 的 image-wrapper_*,其自身 width/height 即方框视觉尺寸)。
  2. 在 index.css 中同时打开 .image-wrapper_*.thumbnail_*(若存在):
    • 槽位尺寸:wrapper 的 widthheight(及 margin-top 等),用于 el-checkbox 根或 .el-checkbox__input 的占位与 flex 居中(常见 16×16)。
    • 方框视觉尺寸优先.thumbnail_*width/height;若无 thumbnail 而 wrapper 本身即为切图区(如 13×13 的 background 盒),则取 该层 的 width/height。此数值用于 ::v-deep .el-checkbox__inner 的 width/height(本页示例为 13×13)。
  3. el-checkbox 设为 display: inline-flex; align-items: center; justify-content: center宽高等于槽位(如 16px),__input 同槽位并 flex 居中,__inner 为步骤 2 的方框视觉尺寸(如 13px),box-sizing: border-box
  4. ::after 勾形:在 inner 边长确定后,按比例微调 heightwidthlefttopborder-width,并在 is-checked .el-checkbox__inner::after 上设 border-color(多为白),使勾与稿面比例接近。

禁止:未打开 index.css 即写死 16×16 inner;或仅看 wrapper 忽略 thumbnail 导致 inner 过大。

需求文案(摘要)

  • 替换伪多选前须从当前页 index.css 读出槽位与方框两层尺寸inner 对齐方框视觉层(多为 thumbnail)根/__input 对齐槽位(多为 wrapper) 并居中 inner。
  • 勾形 ::after 须随 inner 边长缩放,并做选中态勾线色覆盖。

详见 data/recognition-and-fix.md §3.2.3

下拉框替换时必须删除的 DOM(通用规则): 除「当前选中项 + 箭头」的触发区外,若 index.vue 中还有独立的下拉选项列表(如浮层、侧边列表、鼓点-1~鼓点-11 等静态列表),须一并删除。替换为 el-select 后,选项由 el-select 自带的 dropdown 展示,不得保留原静态选项列表 DOM。

修复已有 Custom.vue 时:

  • 若发现「看起来像下拉/多选/搜索但仍是 div+img+span」:按上表替换,并补全绑定与样式覆盖。
  • 若已用 el-select 但页面上仍保留原静态选项列表:删除该静态列表 DOM 及与之相关的 data/methods(如仅用于该列表的 handleXxx)。
  • 搜索框样式异常:按「6.3.1」逐项检查容器高度、.el-input-group 无边框与 flex、el-input__inner 高度与无边框、padding-left、placeholder、prefix 对齐等。

详见 data/recognition-and-fix.md

6.3.5 Element UI 样式覆盖方法

  • 深度选择器:scoped 无法直接修改组件内部样式,须用深度选择器。Vue 2 推荐 ::v-deep,兼容写法 /deep/
  • 写法示例:给组件加父级 class(如 custom_search_input),再写 父级class ::v-deep .el-input__inner { ... },避免影响其他页面。
  • 查找 class:用开发者工具选中组件 DOM,在 Elements 面板查看内部 class(如 .el-input__inner.el-pager li),再用 ::v-deep 覆盖。
  • 优先级:优先用「父级 class + ::v-deep + 组件 class」提高特异性;尽量避免 !important;需覆盖多种状态时写全 :hover:focus.active 等。
  • 输入框示例父级 ::v-deep .el-input__inner 设置 height、border、border-radius、padding、font-size;::v-deep .el-input__inner:focus 设 focus 边框色;::v-deep .el-input__inner::placeholder 设占位符颜色。
  • 分页示例父级 ::v-deep .el-pagination__total 设总数样式;::v-deep .el-pager li::v-deep .el-pager li.active 设页码与选中态;::v-deep .btn-prev, ::v-deep .btn-next 设上下页按钮。
  • 下拉框示例:小尺寸 select 用 父级 ::v-deep .el-input__inner 设 height、line-height、border-radius、font-size、border-color 与设计一致;::v-deep .el-input__inner:focus::v-deep .el-input.is-focus .el-input__inner 设 focus 边框色为页面主题色。下拉选项选中/悬停须用 popper-class + 非 scoped 样式覆盖为主题色,见「6.3.7 下拉框样式与激活态主题色规范」。
  • 多选框示例父级 ::v-deep .el-checkbox__label 设颜色、字号;::v-deep .el-checkbox__inner 的宽高取 方框视觉层(常为 thumbnail,见 6.3.4.3),圆角与设计一致。选中/悬停/焦点须为主题色::v-deep .el-checkbox__input.is-checked .el-checkbox__inner::v-deep .el-checkbox__input.is-indeterminate .el-checkbox__inner 的 background-color、border-color 设为主题色;::v-deep .el-checkbox__inner:hover::v-deep .el-checkbox__input.is-focus .el-checkbox__inner 的 border-color 设为主题色,见「6.3.8」「6.3.8.1」。
  • 单选框示例父级 ::v-deep .el-radio__inner 设尺寸、圆角、边框与设计一致;选中/悬停/焦点须为主题色::v-deep .el-radio__input.is-checked .el-radio__inner 的 border-color、background-color 设为主题色;::v-deep .el-radio__inner:hover::v-deep .el-radio__input.is-focus .el-radio__inner 的 border-color 设为主题色;并覆盖 .el-radio:focus:not(.is-focus):not(:active):not(.is-disabled) .el-radio__innerbox-shadow,见「6.3.10」「6.3.8.1」。

6.3.6 按钮与列表内文字垂直居中规范

改造后若出现「按钮文字、列表 badge 数字、列表项文字」未垂直居中,或按钮在默认态与激活态(hover/active/focus/内容切换)下内容错位,须按以下方式修复并作为通用规则遵守:

场景识别特征修复方法
el-button 默认与激活态按钮有固定高度,文字或图标+文字偏上/偏下/偏左/偏右;或切换状态(hover/active/focus 或内容从「导入」变为「已导入」等)后内容错位在按钮的自定义 class 上通过 ::v-deep默认态及 :hover、:active、:focus 统一设置 display: inline-flex; align-items: center; justify-content: center; line-height: 1;;按钮内文案(span 等)设 text-align: center; margin: 0;(或仅对称 margin),保证默认与激活态内容均水平垂直居中,切换状态时保持居中
按钮激活态/替换态 DOM状态切换后由非 button 的容器(如 div)展示内容,该容器内文字或图标未水平垂直居中该容器使用 display: flex; align-items: center; justify-content: center;(或 inline-flex),内部文案与图标用 text-align: center; margin: 0; 或 flex 居中,与默认态一致
列表/步骤 badge 内文字圆形或方形容器内为数字/序号,须水平垂直都居中badge 容器使用 display: flex; align-items: center; justify-content: center;;内部文字 text-align: center; margin: 0;,不保留左右 margin,实现水平垂直都居中
列表项内文字列表行有固定高度(如 48px),左侧 badge、中间文字、右侧图标未整体垂直居中列表行容器使用 display: flex; align-items: center;;所有子元素(badge、文字、图标)去掉垂直方向 margin(margin-top/margin-bottom 置为 0),由 flex 的 align-items: center 负责垂直居中

自检:el-button 在默认态与 hover/active/focus 及内容切换后,内容均在按钮内水平垂直居中;若有激活态/替换态容器,其内容也水平垂直居中;badge 内文字水平垂直都居中;列表项行内整体垂直居中。若源稿用 margin 实现视觉居中,改造时优先改为 flex 居中并去掉子元素垂直 margin。

6.3.6.1 el-button 根节点 class 与深度选择器(必做,易错)

源稿容器 class写在 <el-button class="[同一容器 class]"> 上时,组件根节点即为 button.el-button.[容器class]不存在「容器在内、.el-button 在子级」的 DOM。禁止用「.容器class ::v-deep .el-button」为该按钮写样式——该选择器只匹配后代中的 .el-button,会导致整段样式不生效,页面仍呈现 Element 默认按钮(错误常见于筛选区「重置」「查询」等)。

环节要求
识别DevTools 查看按钮根节点:若自定义 class 与 el-button 在同一 <button> 上,即属「class 在根节点」。
修复方案 A:用「.容器class.el-button」及 :hover:focus:active 写全尺寸、padding、min-width、背景、边框、字色(必要时 !important)。慎用 type="text"el-button--text 强制透明底/边且三态常回退透明,与稿面「小框+描边/浅底」冲突时须改**默认 type(省略)**或 plain 再覆盖。type="primary" 须覆盖 默认与三态及字色。方案 B:外层再包 div,class 在 div 上,则用「父级 ::v-deep .el-button」。
子节点按钮内 img / span 若沿用源稿 class,常带静态 flex 用的 margin(如 margin: 8px 0 0 16px),须在按钮内 margin: 0,布局交给根上 flex + align-items + justify-content(如主按钮图标+文案 space-between),与 6.3.6 一致。
并排间距主题 .el-button + .el-button { margin-left: 10px } 会叠加稿面间距;须在父行取消或改写,再只用各按钮自身 margin-left 控制。
主按钮type="primary" 时须用「.自定义class.el-button--primary」等覆盖 hover / focus / active 背景、边框、字色,避免状态切换露默认样式。

需求文案(摘要):凡将可点击区改为 el-button 且把原稿容器 class 合并到按钮根上者,样式选择器必须与 DOM 一致;禁止误用「父级 ::v-deep .el-button」;带底/边的次要按钮勿用 type="text";并排按钮须处理默认 10px 相邻间距;子级 img/span 须去源稿 margin。

自检:样式表含 .容器class.el-button(或外层 ::v-deep);默认与 hover、focus、active 与源稿一致;无不当 type="text";并排无多余 10px;子级无破坏 flex 的 margin。

详见 data/el-button-root-and-deep.md(识别步骤、两种修复方案、需求全文、自检清单)。

6.3.7 下拉框样式与激活态主题色规范

  • 触发器样式:el-select 的 .el-input__inner 须用 ::v-deep 设置与设计稿一致的 height、line-height、border-radius、font-size、border-color(默认态);focus 与 hover 态的边框色须使用当前页面主题色(从 index.css 或设计稿中取主色),不得使用 Element 默认蓝色。须同时覆盖:.el-input__inner:hover.el-input__inner:focus.el-input.is-focus .el-input__innerborder-color(Element 在 focus 时给 .el-input 加 .is-focus,漏写则 focus 边框可能仍为默认色)。详见 data/recognition-and-fix.md 9.7。
  • 下拉选项激活态:下拉弹层挂载在 body,scoped 无法覆盖。须给 el-select 设置 popper-class="[folderName]_xxx_dropdown_popper",在 Custom.vue 中增加非 scoped<style> 块,用该 class 覆盖:
    • .popper-class名.el-select-dropdown .el-select-dropdown__item.selected:文字色、背景色为主题色/主题浅色(与设计一致);
    • .popper-class名.el-select-dropdown .el-select-dropdown__item:hover:悬停态文字色、背景色为主题色/主题浅色。
  • 主题色来源:从源页面 index.css 或设计稿中提取主色(如高亮边框、选中项背景、主按钮背景),统一用于 el-select 的 focus 边框、下拉选项 selected/hover,以及列表中选中项边框/文字色等,保证激活态与当前主题一致。

自检:el-select 触发器尺寸与设计一致;focus 与 hover 时边框色均为主题色(见 9.7);下拉选项选中/悬停为主题色,非 Element 默认蓝。

6.3.7.1 el-select 右侧箭头/后缀对齐(必做,易错)

静态稿常用 flex + justify-content: space-between 做「左文案 + 右箭头图」。改为 el-select 后,箭头在 .el-input__suffix(绝对定位) 内,不得把同一套 display:flex; justify-content:space-between 加在 el-select 根节点(与自定义 class 合并处),否则会干扰内部 el-input 布局,表现为右侧图标水平/垂直偏移

另:仅把 .el-input__inner 改为小高度(如 28px)时,Element 默认 .el-input__iconline-height 仍按大输入框(如 40px),箭头会上下不齐;须用 ::v-deep.el-input__icon / .el-select__caretline-heightheight 与 inner 对齐,并设置 .el-input__suffixright(对照 index.css 箭头距右缘)、校验 padding-right 避免文字与箭头重叠。

需求文案(摘要)el-select 触发器右侧箭头位置、垂直居中与右内边距须与稿一致;禁止为复刻静态 flex 在 el-select 根上使用 space-between;改小触发器高度必须同步后缀图标行高/高度与 suffix 定位。

自检:根节点无不当 flex+space-between;suffix right、icon line-height/height 与 inner 一致;文案与箭头不重叠。

详见 data/el-select-suffix-alignment.md(识别、根因、修复步骤、需求全文、自检清单)。

6.3.8 多选框激活态主题色规范

  • 选中态:el-checkbox 默认选中为 Element 蓝色,须用页面主题色覆盖。在 checkbox 的自定义 class 下用 ::v-deep 设置:
    • 父级 ::v-deep .el-checkbox__input.is-checked .el-checkbox__inner父级 ::v-deep .el-checkbox__input.is-indeterminate .el-checkbox__innerbackground-colorborder-color 为页面主题色(与 6.3.7 主题色来源一致)。
  • 悬停态父级 ::v-deep .el-checkbox__inner:hoverborder-color 设为主题色,与设计一致。
  • 焦点态(必做):见 6.3.8.1;仅写 is-checked / :hover 时,键盘聚焦或点击后仍可能露出 Element 默认主色蓝
  • 主题色:与 el-select、列表选中项等统一,从 index.css/设计稿取主色(如 rgba(255, 106, 106, 1));多主色稿面下须与该控件所在区块一致,见 6.3.8.1

自检:多选框选中/半选时方框背景与边框为主题色;悬停时边框为主题色;焦点态(is-focus) 边框为主题色,非 Element 默认蓝。详见 6.3.8.1

6.3.8.1 单选/多选主题色:稿面取色、焦点态与 Element 残留蓝(必做)

问题识别

  1. 只覆盖了选中与 hover,仍见「蓝框」:Element UI 2 在 .el-checkbox__input.is-focus .el-checkbox__inner.el-radio__input.is-focus .el-radio__inner 上使用 $--checkbox-input-border-color-hover / $--radio-input-border-color-hover(即 Element 主题主色,常为 #409EFF),与 Custom.vue 里为「稿面主题色」设置的 is-checked / :hover 不是同一套规则,表现为:点击或 Tab 聚焦后边框仍蓝
  2. 单选独有:焦点环为蓝.el-radio:focus:not(.is-focus):not(:active):not(.is-disabled) .el-radio__innerbox-shadow: 0 0 2px 2px $--radio-input-border-color-hover,未覆盖时整圈仍为默认蓝。
  3. 主题色选错(多主色页面):同一 index.css 中常并存 导航/Tab 高亮蓝(如 rgba(0, 116, 252, 1))与 主按钮/设置区/勾选切图色(如 rgba(4, 180, 182, 1))。将前者套到设置面板内el-checkbox / el-radio 会导致与静态勾选 PNG、邻近竖条(section_*)、主按钮不一致。

修复方法(在控件父级自定义 class 下 ::v-deep,与已写的 checked/hover 同色)

状态el-checkboxel-radio
焦点(键盘/点击后 input 带 .is-focus父级 ::v-deep .el-checkbox__input.is-focus .el-checkbox__inner { border-color: [稿面主题色]; }父级 ::v-deep .el-radio__input.is-focus .el-radio__inner { border-color: [稿面主题色]; }
单选:原生 focus 环父级.el-radio:focus:not(.is-focus):not(:active):not(.is-disabled) ::v-deep .el-radio__inner { box-shadow: 0 0 2px 2px [稿面主题色半透明]; }(或与稿一致改为 none

稿面主题色怎么取(须自当前页 index.css,禁止抄其它页 Custom)

  1. 定位该控件在 index.vue 中对应的静态结构(原勾选/单选切图、或同一块卡片内的主按钮、标题竖条 background-color)。
  2. index.css 中查 .thumbnail_* / .image-wrapper_* 背景同区主按钮section_* 装饰条background-color / border-color,取与交互控件一致的那一支作为主色。
  3. 同一页el-pagination、列表 Tab 若用蓝 A,设置区勾选若用青 B,则 checkbox/radio 须用 B,不得统一成 A。

需求文案(摘要)

  • 替换 el-checkbox / el-radio 后,选中、悬停、焦点(.is-focus)及单选 box-shadow 焦点环须全部使用该区块稿面主题色,不得残留 Element 默认蓝。
  • 主题色须从当前文件夹 index.vue + index.css 就近提取;多主色时表单控件与静态勾选/主按钮同色,不得误用仅用于列表或 Tab 的色值。

自检:DevTools 选中 .el-checkbox__input / .el-radio__input,手动切换 :focus、查看是否带 .is-focus,确认 inner 边框与(单选)box-shadow 均为稿面色;与 index 静态区主色对比一致。

详见 data/radio-checkbox-theme-and-focus.md(识别步骤、选择器对照、需求全文)。

6.3.9 分页(el-pagination)替换与主题色规范

  • 替换时必须删除的 DOM:分页区域整块替换为单个 el-pagination 时,须删除该区域内全部原始静态内容,包括「共 xxx 条」文案与图标、所有静态页码块(如 1、2、3…)、上一页/下一页的静态图标或按钮、「xx条/页」的静态或伪下拉。不得在 el-pagination 外再保留一份上述内容,否则会出现两套分页。
  • layout:使用 layout="total, prev, pager, next, sizes",由组件自带展示总数、上下页、页码、每页条数。
  • 样式:用 ::v-deep.el-pagination__total.btn-prev/.btn-next.el-pager li.el-pagination__sizes .el-input__inner 设置与设计一致的尺寸、边框、圆角、字号。上一页/下一页按钮须设 padding: 0display: inline-flexalign-items: centerjustify-content: center 使图标居中,并设默认态 color,内部 .el-iconcolor: inherit(见 recognition-and-fix 9.6)。
  • 激活态/主题色当前页 .el-pager li.active 的背景色、边框色须为页面主题色;上一页/下一页 hover 态须同时设边框色与图标色为主题色(须为 .btn-prev:hover.btn-next:hovercolor,并为 .btn-prev:hover .el-icon.btn-next:hover .el-iconcolor,见 9.5);页码 .el-pager li:hover 边框/文字色为主题色;每页条数 sizes 的 el-select 触发器(.el-input)须在 focus 与 hover 时边框均为主题色(须同时覆盖 .el-input__inner:hover.el-input__inner:focus.el-input.is-focus .el-input__inner,见 9.7)。
  • sizes 下拉主题色:el-pagination 内部的「每页条数」为 el-select,其下拉层挂载在 body 且无法单独设置 popper-class。须在 Custom.vue 中增加非 scoped<style>同时覆盖选中态(.selected)、键盘焦点态(.hover)、悬停态(:hover)及选中+悬停(.selected:hover.selected.hover),对 colorbackground-color 使用 !important若 hover 仍不生效须使用双重 class 提高特异性(如 .el-select-dropdown .el-select-dropdown__item.el-select-dropdown__item:hover)或 body .el-select-dropdown .el-select-dropdown__item,使 sizes 下拉的选中项与悬停项与页面主题一致。详见 data/recognition-and-fix.md 第 3.4、9.4 节。

自检:已删除原始分页全部静态内容,仅保留一个 el-pagination;上一页/下一页 按钮图标居中、默认态与 hover 态颜色正确(见 9.6、9.5);sizes 的 el-select 触发器 focus 与 hover 时边框均为主题色(见 9.7);当前页、sizes 下拉选中/悬停均为主题色(见 9.4)。

6.3.10 单选框(el-radio)识别与主题色规范

  • 识别:源页面存在「多选一」互斥选择(如多个选项中仅能选一项),包括原生 <input type="radio"> 或 div + 文案/图标模拟的单选区域,须替换为 el-radio-group + el-radio
  • 替换:删除原单选区域全部 DOM,改为 <el-radio-group v-model="radioValue" class="[folderName]_radio_group"> + <el-radio v-for="..." :label="..." :key="...">...</el-radio>;在 data 中定义选中值(如 radioValue),在 methods 中实现 @change 处理(如 handleRadioChange)。
  • 样式与源页一致:用 ::v-deep.el-radio__inner.el-radio__label 等设置与 index.css/设计稿一致的尺寸、圆角、边框、字号、颜色;整体布局(横向/纵向、间距)与源页面一致。
  • 激活态与选中项主题色:Element 默认选中为蓝色,须改为页面主题色。在单选框父级 class 下用 ::v-deep 设置:
    • 选中态父级 ::v-deep .el-radio__input.is-checked .el-radio__innerborder-colorbackground-color 为页面主题色(与 6.3.7/6.3.8 主题色来源一致);父级 ::v-deep .el-radio__input.is-checked + .el-radio__label 的文字色可设为主题色或与设计一致。
    • 悬停态父级 ::v-deep .el-radio__inner:hoverborder-color 设为主题色。
    • 焦点态与焦点环(必做):见 6.3.8.1.is-focus 边框 + .el-radio:focus:not(...)box-shadow)。
  • 主题色来源:从 index.css 或设计稿中取主色(如选中项背景、主按钮背景),与 el-select、el-checkbox 等统一;多主色稿面下与设置区静态控件一致,见 6.3.8.1

自检:单选项已替换为 el-radio-group + el-radio;尺寸、布局、文字与源页一致;选中项与悬停态圆点/边框为主题色;焦点态与 focus 环为主题色,非 Element 默认蓝(见 6.3.8.1)。

6.3.10.1 筛选项折行与高度自适应(必做,适用时)

将横向筛选改为 el-radio-group 后,若在较窄宽度或选项较多时允许折行,须避免固定高度裁切行间重叠

环节要求
筛选外层卡片勿用固定 height 锁死整张筛选卡;改为 min-height: [设计稿高度] + height: auto,并设 padding-bottom,使多行选项撑开卡片。
筛选行(标签 + 选项组)行容器 flex-wrap: wrapalign-items: flex-start(或 align-content: flex-start),gap 控制换行后的纵向/横向间距;行宽在 max-width 与面板一致下可用 width: 100% 覆盖稿中过窄的固定 width
左侧标签flex-shrink: 0height: auto + min-height: [原行高],与选项首行对齐,避免固定 height 与折行冲突。
el-radio-groupflex: 1min-width: 0flex-wrap: wraprow-gap / column-gap 统一选项间距;减少纯 margin-left,避免换行后首列/次行边距错乱。
.el-radio / __label使用 min-height 对齐设计行高,height: auto;必要时 padding + line-height,避免文字与背景 pill 上下被裁切。
名称行(标签 + 搜索)若与筛选区上下相邻,该行勿用固定 height 压过折行后的筛选区;改为 min-height + height: auto,必要时 flex-wrap + gap

识别要点:在 Custom.vue 的 scoped 样式中搜索筛选相关容器的 height:;若筛选行已 flex-wrap: wrap 仍重叠,优先查外层卡片与子行是否仍为固定高度、选项组是否缺 min-width: 0、间距是否仅依赖 margin-left

自检:缩小视口或增加选项后,筛选区自动增高无与下一行筛选或列表重叠;选项多行时间距清晰;设计宽度下单行布局仍与稿面基本一致。

详见 data/filter-row-wrap.md(识别步骤、修复细则、需求文案、自检清单)。

取色组件选型(摘要):颜色选择均由 触发区 + 下拉面板 组成;以下拉面板的版式 判断图1 / 图2,不以触发区(色块、A 字条等)单独判断。图1(预设矩阵类「填充」面板等)→ el-color-picker-extend图2(Element 默认取色下拉:SV + 竖色相条 + 清空/确定)→ el-color-picker。替换后须 删除 原静态或重复的取色 DOM,避免两套 UI 并存。识别清单、需求文案与错配修复见 data/el-color-picker-extend.md §「颜色选择:触发与下拉的共同结构」、§「图1 / 图2 对照与识别清单」、§「常见错配与修复」。

6.3.11 el-color-picker(图2)与页内静态「填充」删除;el-color-picker-extend(图1)集成注意(必做,适用时)

环节要求
通用规则触发与下拉:点击后展开的区域才是选型依据;图1、图2 的 触发区都可以是「颜色选择按钮」类控件,区别仅在 展开内容 是稿面定制填充面板还是 Element 默认面板。详见 data/el-color-picker-extend.md §「颜色选择:触发与下拉的共同结构」。
识别(稿面)图2:若展开 look 为 SV 大方块 + 右侧竖向色相条 + 底栏 Hex +「清空」「确定」el-color-picker;常见 触发 为「字体颜色」行 小框:A + 下划色条 + 箭头(静态多为 A + png + 绝对定位色条)→ 用 透明叠层 盖住触发区。图1:展开为 标题「填充」+ 色块矩阵 + 滑条 + #hex + % + RGB +「最近使用」 等(页内整区或弹层)→ el-color-picker-extend,并 删除 原静态切图/伪输入整段 DOM。
触发器样式需与稿一致时:用 A(与 index.css 字号/字色一致)+ 横向色条background-color 绑定 v-model 当前色,透明时用 transparent)+ 右侧三角(CSS border 或 8×8 内联图)。假设 Element UI 2.x 提供 #trigger 插槽()。
实现图2(el-color-picker透明触发区覆盖:外层 position: relative,底层为 可见 自定义面(pointer-events: none),上层 el-color-picker 绝对定位铺满,对 ::v-deep .el-color-picker__trigger宽高 100%、无边框、opacity: 0,保证点击落在官方触发器上;对根节点 .el-color-picker 整体 opacity: 0,否则 下拉面板 会被一并隐藏。popper-class 仍用于挂载到 body 的下拉样式。
实现图1(el-color-picker-extend在页面中放置 <el-color-picker-extend v-model="fillColorRgba" recent-storage-key="..." />(工程内全局注册),删除 原页内填充区全部静态节点;父容器若在 index.css 中 固定高度,须改为 height: auto(或加修饰 class 覆盖),见 data/el-color-picker-extend.md
删除页内块已用 el-color-picker-extendel-color-picker 承担取色后,须 删除 index 稿中 整块 原「填充」模拟区(多图色矩阵、独立渐变条图、#hex、RGB 行、静态「最近使用」色块行等),禁止在页面内再保留一套取色 UI;扩展组件内置「最近使用」时不得与静态切图并存。
多行相同控件多条「字体颜色」行共用同一 v-model 即可;每行一个 el-color-picker(透明覆盖)或仅一行有 picker(另一行只读展示)按稿面二选一,避免重复逻辑分叉。

需求文案(摘要)

  • 图2 字体颜色A + 随当前色变化的下划线 + 下拉示意,用透明 el-color-picker 覆盖点击;不得整页 opacity: 0 包住取色组件。
  • 图1 填充区:用 el-color-picker-extend 后:删除 原静态「填充」页内大面板(色格/滑条图、拼出来的 hex/rgb/最近使用等),不重复保留模拟弹层。

自检:工具条视觉与 index 一致;点击能打开官方取色下拉;下拉内操作正常;页面无第二套静态取色/最近使用切图。

详见 data/el-color-picker-extend.md §「字体颜色触发器(Element UI 2)」

6.4 循环渲染规范

将重复的结构改为 v-for 循环:

<!-- ❌ 改造前(静态重复) -->
<div class="item">内容1</div>
<div class="item">内容2</div>
<div class="item">内容3</div>

<!-- ✅ 改造后(动态循环) -->
<div 
  v-for="(item, index) in itemList" 
  :key="item.id" 
  :class="['item', getItemClass(index)]"
>
  {{ item.content }}
</div>

6.5 图片路径处理规范(⭐重要)

⚠️ 路径基准: Custom.vueindex.vue 同目录,位于视图文件夹根(如 src/views/shushi/),图片实际在 src/views/${folderName}/assets/img/。所有路径均相对于 Custom.vue 所在目录 解析。

场景正确做法错误做法
Template 中的 <img> 标签:src="require('./assets/img/xxx.png')" 或 data 中 require('./assets/img/xxx.png'):src="require('./img/xxx.png')"
Custom.vue 内 <style> 中的 background-imageurl(./assets/img/xxx.png)url(./img/xxx.png)
data() 中定义的图片路径img: require('./assets/img/xxx.png')img: require('./img/xxx.png')

为什么 Custom.vue 里 CSS 必须用 ./assets/img/

  • 源文件 assets/index.cssassets/ 下,其中 url(./img/xxx) 是相对于 assets 目录 的,指向 assets/img/,在 index.css 中正确。
  • 样式内联到 Custom.vue 后,构建时相对路径的基准是 Custom.vue 所在目录(视图文件夹根),./img/ 会解析到不存在的 视图文件夹/img/,导致图片 404。
  • 因此写入 Custom.vue 的 CSS 中必须使用 url(./assets/img/xxx.png),才能正确指向 视图文件夹/assets/img/

识别与修复(通用流程):

  1. 识别(以稿源 CSS 为准)

    • ${folderName}/assets/index.css(及其链式 @import)中搜索:
      • url(./img/url("./img/url('./img/(含单/双引号与无引号)
      • background: / background-image:(定位所有背景图声明,包含 sprite/mergeImage)
    • index.vue 中搜索:src="./assets/img/src='./assets/img/:src=(定位所有 <img> 引用)
  2. 写入 Custom.vue 时的规则(必须执行)

    • Template / data():图片路径统一为 require('./assets/img/文件名')
    • <style scoped>:从 index.css 拷贝过来的背景图路径,凡 url(./img/xxx) 一律改为 url(./assets/img/xxx)
  3. 修复已有 Custom.vue(问题排查顺序)

    • 背景区域图片样式异常 / 背景图不显示
      1. 在 Custom.vue 的 <style scoped> 中搜索 url(./img/,若存在则全局替换为 url(./assets/img/
      2. 检查是否误写成 url(@/...)url(/...)(本 Skill 禁止),统一改为 url(./assets/img/...)
      3. 检查迁移时是否丢了 background 的关键子属性:background-repeatbackground-positionbackground-size(如源为 background: url(...) 100% no-repeat; background-size: 100% 100%;),必须完整迁移,否则会表现为「背景拉伸不对/不铺满/位置偏移」。
    • <img> 不显示:检查是否为 require('./assets/img/xxx'),勿用 require('./img/xxx')

修复自检清单:

  • Custom.vue 的 style 中:不存在 url(./img/...),所有背景图均为 url(./assets/img/...)
  • Custom.vue 的 template/data 中:不存在 require('./img/...),所有图片均为 require('./assets/img/...)
  • 对每个背景块核对:background 四要素(image / repeat / position / size)与 index.css 一致

6.6 数据与方法同步生成

❌ 禁止分步执行:

<!-- 错误:只写 template,不写 data 和 methods -->
<template>
  <el-input v-model="inputValue" @change="handleChange" />
</template>
<script>
export default {
  // data 和 methods 稍后补充
}
</script>

✅ 必须同步完成:

<template>
  <el-input v-model="inputValue" @change="handleChange" />
</template>
<script>
export default {
  data() {
    return {
      inputValue: ''  // ✅ template 中使用的数据必须定义
    }
  },
  methods: {
    handleChange() {  // ✅ template 中的事件必须实现
      // 处理逻辑
    }
  }
}
</script>

6.7 样式匹配标准(按元素重要性)

改造后视觉效果须与源文件一致,按元素类型采用不同匹配级别:

标准适用场景必须匹配的属性
完整匹配列表项、卡片、主容器盒模型 + 尺寸 + 布局 + 文字 + 边框 + 视觉效果 + 交互状态
简化匹配筛选项、按钮、标签尺寸 + 布局 + 文字 + 边框 + 视觉效果 + 交互状态
文字匹配标题、描述文本font-family、font-size、color、font-weight、line-height
尺寸匹配图片、图标width、height、border、border-radius、box-shadow

布局与验证:PC 端流式布局用 width: 100%、百分比宽度,优先 Flex/Grid;尺寸、颜色、字体、间距等用浏览器开发者工具对比 Computed 样式,误差不超过 1px,颜色精确到 rgba。若样式不一致,检查选择器优先级、是否需 ::v-deep 覆盖、是否有冲突样式。

6.8 列表项内容溢出规范(v-for 列表必做)

凡用 v-for 渲染的列表/卡片,其项内由数据驱动的文本(标题、作者、描述等)不得沿用 index.css 中该文本的固定 width/height,否则长文案会溢出。须按 data/list-item-overflow.md 执行:

  • 列表项根节点:设 overflow: hiddenbox-sizing: border-box;若项内有固定宽高的内容区(如 first-inner),也设 overflow: hiddenmin-width: 0
  • 动态文本节点:将固定 width/height 改为 max-width(按内容区可用宽度取值),保留 overflow-wrap: break-word,并加 overflow: hidden、必要时 min-width: 0(flex 子项)。不得为「与设计稿数值一致」保留会导致溢出的固定宽度。

详见 data/list-item-overflow.md(识别步骤、修复方法、需求文案、自检清单)。

6.9 文字竖排与横排识别(必做)

改造时须根据 index.css 与设计稿识别列表/卡片内标题、作者等为竖排还是横排,避免将竖版做成横版。识别规则见 data/text-direction-vertical-horizontal.md

  • 竖排:index.css 中该文本为窄宽高瘦(width 约 14px~24px、height 明显大于 width、line-height 与 width 接近),或设计语义为古诗词/传统竖版 → 在 Custom.vue 中为该节点设 writing-mode: vertical-rl(或 vertical-lr)、text-orientation: uprightdisplay: inline-block(若为 span),并设与设计一致的 width、max-height、line-height、overflow: hidden。竖排下的复合文案(如「朝代·作者」)若设计为单列,须用单段拼接,不得用 <br>(否则竖排会变多列),见 data/text-direction-vertical-horizontal.md 4.2。
  • 横排:无上述特征或为常规 UI 文案 → 不设 writing-mode,按横排布局处理。

详见 data/text-direction-vertical-horizontal.md(识别步骤、修复方法、需求文案、自检清单)。

6.10 列表样式(单行不换行)(必做)

凡用 v-for 渲染且设计上为单行横向排布的列表/卡片项(如左装饰 + 内容 + 标题 + 作者 + 右装饰等),列表项根节点若为 flex 横向布局,须设 flex-wrap: nowrap,不得使用 flex-wrap: wrap,避免项内换行导致错位。列表项根节点须同时设 overflow: hiddenbox-sizing: border-box(与 6.8 一致)。详见 data/list-style.md(识别步骤、修复方法、需求文案、自检清单)。

6.11 列表行高度与对齐规范(必做)

凡用 v-for 渲染的列表,其列表行(普通行、第一行、第二行等)必须满足以下要求,避免文字被截断和右侧列对齐问题:

  • 高度修复:列表行使用 min-height 而非仅固定 height(如 min-height: 23px; height: 23px;),确保行内文字(line-heightheight 一致)不被截断;行内元素需设置 min-heightheight 一致(如 min-height: 22px; height: 22px;)。
  • 对齐修复:列表行内各列(如课包名、讲次信息、状态信息、更新信息)需设置固定宽度(从 index.css 中查找对应列的宽度,如 .image-text_4 { width: 134px; }),并设置 flex-shrink: 0 防止在 flex 布局中被压缩;各列的 margin-left 值需与 index.css 中的值完全一致(误差不超过 1px)。
  • 溢出处理:列内文本(如课包名)可用 max-width + overflow: hidden + text-overflow: ellipsis 防止溢出,但列容器本身需保持固定宽度。
  • 多 rowKind 统一行高与列槽(表格形列表必做):若同一列表存在多种 rowKind(首行灰底、高亮行、普通双列、续讲无左列等),须 (1) 以静态稿最高行为统一 min-height 基准,列表项外层与内层行轨道共用 align-items: center(2)固定宽度课包列槽(宽度 = index.css 首行课包区宽度),normal 与续讲行均经该槽对齐,续讲行用空槽占位,禁止单独使用超大整行 margin-left 顶替列槽;(3) 讲次列紧贴槽右缘用统一间距(如 20px),项间距仅用 .list_item + .list_item(或统一 padding),禁止「仅某类行」的相邻兄弟外边距分叉;(4) 行内子元素垂直对齐以 flex 为主,margin-top 置 0(绝对定位结构除外)。

详见 data/list-row-height-alignment.md(含第 8 节:多 rowKind 统一行高与列槽对齐;识别步骤、修复方法、需求文案、自检清单)。

6.12 双列列表左右数据源独立(必做,适用时)

若列表在语义上为左列 + 右列(如课包 + 讲次/状态/更新),且存在续讲等行左侧无单元格或两侧数据将来来自不同接口,须:

  • 使用 packageList(左)与 lectureList(右)等两套独立 data,不得以单一合并对象为唯一数据源;v-for 通常以右侧(明细)列表为主循环,左侧用 packageList[index] 对齐。
  • 左侧无内容行:左列数据用 title: null(或等价),并设 rowKind(如 right_onlyright_only_compact)走独立 template + 独立样式类,margin/width 对照 index.css 中单独 group,禁止用空字符串 + 普通双列行凑合。

详见 data/list-dual-column-independent.md(识别步骤、修复方法、需求文案、自检清单)。

步骤 7: 验证生成的代码

生成 Custom.vue 后,必须进行以下验证:

7.1 样式检查

  • 尺寸与源文件一致(误差不超过 1px)
  • 颜色完全一致(rgba 值相同)
  • 字体、间距完全一致
  • 视觉效果与源文件 100% 匹配
  • 带外框的搜索框:容器高度与设计一致,容器有 border,hover 与 focus-within 时边框为主题色(见 9.8),无双重边框,前缀图标与文字垂直对齐,placeholder 与输入文字垂直居中,placeholder 颜色正确,无错位或溢出;容器设 max-width、min-width: 0,所在行设 min-width: 0,不溢出父级(见 6.3.1、6.3.1.1、data/search-input-and-page-overflow.md)
  • 页面不横向溢出:主卡片/底栏/搜索框所在行使用 width:100%+max-width+min-width:0;底栏中间文案用 margin-left:auto;无横向滚动(见 6.3.1.1、data/search-input-and-page-overflow.md)
  • 垂直居中:el-button 及 div+背景图+文字按钮内文字均水平与垂直都居中,文字节点 width: 100%、margin: 0、display: inline-flex + align/justify center,无单侧 margin 导致偏位;列表/步骤 badge 内文字水平垂直都居中;列表项内文字与图标均在容器内垂直居中(见 6.3.6、recognition-and-fix 9.2)
  • el-button 与深度选择器:自定义 class 在按钮根上时,已用 .class.el-button 或外层包裹 + ::v-deep误用「.class ::v-deep .el-button」导致重置/查询等样式不生效(见 6.3.6.1、data/el-button-root-and-deep.md
  • el-button 类型与三态:带底/边次要按钮未误用 type="text";已写全 :hover / :focus / :active;并排已处理 .el-button + .el-button;子 img/span 无源稿静态 margin(见 data/el-button-root-and-deep.md 2.1~2.3)
  • 下拉框与激活态主题色:el-select 触发器 focus 与 hover 边框色均为主题色(须覆盖 :hover、:focus、.el-input.is-focus .el-input__inner,见 9.7),下拉选项选中/悬停为主题色;分页 sizes 等挂载 body 的下拉须用非 scoped 样式覆盖选中/悬停为主题色,未生效时用 !important(见 6.3.7、recognition-and-fix 9.1、9.7)
  • el-select 右侧箭头对齐:未在 el-select 根上误用 flex+space-between;小高度触发器已同步 .el-input__suffix / .el-input__icon.el-select__caret)与 padding-right(见 6.3.7.1、data/el-select-suffix-alignment.md
  • 多选框激活态主题色:el-checkbox 选中/半选/悬停为主题色(见 6.3.8)
  • 纵向模块勾选列:配置/预览区左列 16×16 方框列已改为 el-checkbox,已删方框切图;moduleFlags(或等价)与右侧 v-show 联动;无内联文案时已隐藏 .el-checkbox__label(见 6.3.4.1、recognition-and-fix.md §2.2.1、§3.2.1)
  • 横向工具条 / 尾行勾选:英式音标、鼓点音频、单词书写等横排/尾行左侧方框已改为 el-checkbox,无静态图残留;IPA 区、鼓点控件、书写预览等已 v-show 联动;「全选所有模块」已包含上述布尔(见 6.3.4.2、recognition-and-fix.md §2.2.2)
  • 多选框尺寸全页统一:模块勾选共用同一 class 与同一套 ::v-deep(根、__input__inner__inner::after、选中勾线色),与 index.css 方框一致,无混排(见 6.3.4.2、recognition-and-fix.md §3.2.2)
  • 多选框 inner 与槽位分层:已从 index.css 核对 wrapper 槽位thumbnail(或内层 wrapper)方框视觉 宽高;el-checkbox__inner 与方框视觉层一致,__input/根与槽位一致并居中 inner,非笼统 16×16 inner(见 6.3.4.3recognition-and-fix.md §3.2.3)
  • 单选框:已替换为 el-radio-group + el-radio;样式与源页一致;选中项与悬停态为主题色(见 6.3.10)
  • 筛选折行:筛选项可折行时,筛选卡片与各筛选行使用 min-height + 自动增高gap 控制间距,el-radio-group 具备 flex:1、min-width:0、flex-wrap,无行间/与列表重叠(见 6.3.10.1、data/filter-row-wrap.md)
  • 分页:已删除原始分页全部静态内容,仅保留一个 el-pagination;sizes 的 el-select 触发器 focus 与 hover 时边框均为主题色(见 9.7);上一页/下一页 已设 padding:0、inline-flex、居中及默认态 color(见 9.6),hover 时边框与 .el-icon 均为主题色(见 9.5);sizes 下拉选中/悬停均为主题色,未生效时已用双重 class 或 body 前缀及 !important(见 6.3.9、recognition-and-fix 9.4、9.5、9.6、9.7)
  • 列表项内容不溢出:v-for 列表项根节点已设 overflow: hidden、box-sizing: border-box;动态文本已用 max-width + overflow-wrap + overflow: hidden,无固定 width/height 导致溢出(见 6.8、data/list-item-overflow.md)
  • 列表行高度与对齐:v-for 列表行(普通行、第一行、第二行等)已使用 min-height 而非仅固定 height,行内元素已设 min-height 确保文字不被截断;各列(如课包名、讲次、状态、更新)已设置固定宽度(从 index.css 查找)、flex-shrink: 0,各列 margin-left 值与 index.css 完全一致(误差不超过 1px);在浏览器中确认文字完整显示、右侧列位置与设计稿一致(见 data/list-row-height-alignment.md)
  • 多 rowKind 统一行高与列槽:若存在多种 rowKind,列表项已统一 min-height 与行轨道 align-items:center;已设课包列槽 W_package,续讲行为空槽而非整行超大 margin-left;讲次列起点统一;项间距无「仅某类行」分叉(见 data/list-row-height-alignment.md 第 8 节)
  • 双列列表左右独立:若为左列+右列表格形列表,已使用两套独立数据源(如 packageList + lectureList),续讲/无左列行已用 rowKind 与独立布局类,未用单对象合并左右字段或空 courseName + 普通行冒充(见 6.12、data/list-dual-column-independent.md)
  • 文字竖排/横排与设计一致:已根据 index.css「窄宽高瘦」与设计语义识别竖排;竖排节点已设 writing-mode、text-orientation: upright、display: inline-block(若为 span)及 width/max-height/overflow;竖排复合文案(如朝代·作者)未用 <br>,作者区无塌陷错位(见 6.9、data/text-direction-vertical-horizontal.md)
  • 列表项单行不换行:单行设计的 v-for 列表项根节点已设 flex-wrap: nowrap、overflow: hidden、box-sizing: border-box,项内无换行错位(见 6.10、data/list-style.md)

7.2 功能检查

  • 循环渲染正常工作
  • Element UI 组件正常显示和交互
  • 取色 / 填充:已按稿面 图1 / 图2 选用 el-color-picker-extendel-color-picker(见 data/el-color-picker-extend.md §选型),并已 删除 原静态/重复取色 DOM;图2「字体颜色」工具条已按 6.3.11 做 A+下划线+箭头;按该文档 自检集成注意(如父级 height: auto)逐项核对
  • 每个组件使用的数据均在 data() 中定义,每个事件绑定(@click、@change、@size-change 等)均在 methods 中实现
  • 所有可点击按钮均已绑定 @click 并实现对应 handleXxx 方法
  • 所有点击事件有响应,数据绑定正确

7.3 代码质量检查

  • Class 命名符合规范(无数字、无连字符、无驼峰)
  • 所有数据在 data() 中定义
  • 所有方法在 methods 中实现
  • 没有未使用的变量
  • 没有 console.log(除非必要)

搜索框样式异常时:按 6.3.1 带外框搜索框规范检查——外层容器 flex + align-items: center + box-sizing: border-box;el-input 高度 100%;el-input__inner 高度略小于容器、无重复边框、背景透明、border-radius 与容器一致;placeholder 用 ::v-deep .el-input__inner::placeholder 设置;el-input__prefix 与自定义图标垂直居中。

7.4 路由登记检查(交付必做)

  • 已在路由文件中为 src/views/${folderName}/ 补充与项目约定一致的访问路径(常见:静态 index.vue动态 Custom.vue 各一条,如 /shushi/shushi-custom)。
  • import 路径指向真实文件,component 与变量一致,无重复 path / name
  • 本地访问新路径无 404,控制台无组件加载错误。

识别步骤、修复模板、需求文案与自检全文见 data/router-sync.md

步骤 8: 路由登记与校验(Custom.vue 写入完成后)

Custom.vue 生成或更新已落盘 之后执行(可与步骤 7 并行收尾,但须在交付前完成):

  1. 读取项目路由入口(本仓库为 src/router/index.js)。
  2. 搜索 ${folderName}views/${folderName}/Custom.vue;对照仓库内已有视图(如 gushiyingyu)的 静态 + 动态 成对路由约定。
  3. 缺失则补全import 两个组件(index.vueCustom.vue),在 routes 中追加 path / name / component,风格与现有条目一致。
  4. 自检:浏览器打开新 path,确认页面渲染且无报错。

禁止:根据路由反推当前页 UI;不得省略本步骤导致 Custom.vue 仅存在于磁盘却无法访问。


data/ 文档索引

详细规范说明请参考 data/ 目录下的文档:

分类文件主要内容
项目配置data/project-config.md文件路径、技术栈、改造目标、改造前后示例
核心规范data/style-consistency.md样式一致性、响应式布局、验证方法
核心规范data/class-naming.mdCSS 类命名规范 + Class 重命名强制要求
核心规范data/render.md循环渲染、v-for、图片路径、常见错误
核心规范data/element-ui-style.mdElement UI 替换规范、样式覆盖与深度选择器
核心规范data/style-match-standard.md按元素重要性的样式匹配标准
执行流程data/execution-flow.md执行前准备、开发原则、组件同步生成、验证流程
任务清单data/tasks.md任务 1~5 的步骤与验收标准
验证与验收data/validate.md最终验证清单:样式 / 功能 / 代码质量检查
常见问题data/faq-solutions.md样式、循环、图片、布局、交互等常见问题及解决方案
识别与修复data/recognition-and-fix.md下拉框、多选框、纵向模块勾选列(§2.2.1、§3.2.1)横向/尾行(§2.2.2)多选尺寸统一(§3.2.2)多选尺寸读取 wrapper/thumbnail(§3.2.3)单选框(含折行见 filter-row-wrap.md)、带外框搜索框、分页背景区域图片样式 / 背景图不显示的识别与修复;按钮与列表内文字垂直居中的识别与修复(含自检清单)
识别与修复data/search-input-and-page-overflow.md带外框搜索框 placeholder 垂直居中输入框/底栏按钮不溢出页面的识别、修复与需求文案
识别与修复data/list-item-overflow.md列表项内容溢出:v-for 列表内动态文本的识别、修复(max-width/overflow)、需求文案与自检
识别与修复data/list-row-height-alignment.md列表行高度与对齐 + 多 rowKind 统一行高与列槽:min-height、固定列宽、flex-shrink;表格形多行类型列表的统一行高、课包列槽、续讲空槽、项间距与 flex 垂直居中;需求文案与自检(含第 8 节)
识别与修复data/list-dual-column-independent.md双列列表左右独立:左列+右列数据源分离、续讲无左列行 rowKind 与独立布局、禁止单对象硬合并与空字段冒充
识别与修复data/text-direction-vertical-horizontal.md文字竖排与横排:根据 index.css 窄宽高瘦与设计语义识别竖排/横排,修复(writing-mode)、需求文案与自检
识别与修复data/list-style.md列表样式(单行不换行):v-for 列表项为单行横向排布时 flex-wrap: nowrap、overflow/box-sizing,识别、修复与自检
识别与修复data/filter-row-wrap.md筛选项折行与高度自适应:筛选卡/筛选行固定 height 裁切、el-radio-group 换行间距、gap 替代 margin 链;需求文案与自检
识别与修复data/el-button-root-and-deep.mdel-button:根 class 与 ::v-deep;勿用 type="text" 冒充带框次要按钮;相邻 10px;子 img/span 去 margin;三态与 primary 字色
识别与修复data/el-select-suffix-alignment.mdel-select 后缀箭头:禁止根节点 flex+space-between;小高度须同步 icon line-height、suffix right、padding-right
识别与修复data/el-color-picker-extend.md触发与下拉共同结构图1 / 图2 对照清单、选型/错配修复、需求文案(评审可粘贴)el-color-picker-extendel-color-picker 细则、字体颜色触发器、Props/事件、自检;与 6.3 / 6.3.4 / 6.3.11 交叉引用
交付与工程data/router-sync.md路由登记Custom.vue 交付后登记 index/Custom 路由;识别 404/未 import、与稿源关系、自检清单
关键要求data/requirements.md文件操作、执行原则、代码规范、数据与方法完整性
流程总结data/workflow-summary.md完整开发流程、检查点、快速参考流程图

执行完成后

  1. 报告执行结果:告知用户 Custom.vue 文件已生成,并说明主要改造内容
  2. 列出修改清单:说明完成了哪些改造(循环渲染、Element UI 替换等)
  3. 路由:说明是否已按 data/router-sync.md 检查/更新路由,并给出可访问的 path(如 /shushi-custom);若用户环境路由文件路径不同,注明需自行同步
  4. 打印模型信息:在回复最后打印本次执行所使用的 AI 模型名称与版本信息

快速参考:执行流程图

用户触发 Skill
    ↓
提取 folderName
    ↓
验证源文件存在(index.vue + index.vue 所引用的 CSS)
    ↓
读取源文件(仅上述文件,不读其他工程文件)
    ↓
分析页面结构(布局、重复结构、交互元素)
    ↓
生成 Custom.vue(Write 工具直接写入文件)
    ↓
验证代码质量(含 7.4 路由登记)
    ↓
登记/校验路由(步骤 8,见 data/router-sync.md)
    ↓
报告执行结果 + 可访问 path + 打印模型信息

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

General

中国大陆AI保险顾问

中国大陆AI保险顾问。为个人和家庭提供全方位的保险咨询、产品对比、方案设计、投保指导。当用户询问保险配置、保险方案、产品对比、重疾险/医疗险/寿险/意外险/储蓄险推荐、保费计算、保障缺口分析、需求分析、核保合规、理赔等问题时使用。

Registry SourceRecently Updated
General

Four Dimensional Deep Reading

Simultaneously analyze books using 4 personas with multi-dimensional methods, producing structured insights on first principles, comparisons, and diverse per...

Registry SourceRecently Updated
General

🫧 Kling 3.0 — Pro Pack on RunComfy

Kling 3.0 video generation on RunComfy. Kling 3.0 (also called Kling V3.0) is Kuaishou Technology's third-generation multi-shot video model with native synch...

Registry SourceRecently Updated
General

App Builder

Full-stack application builder that creates web apps, APIs, mobile apps, and more from natural language requests. Use when the user wants to build a new appl...

Registry SourceRecently Updated