newlifex/newlife.cube/cube-page-override

Claude Code and agent skill by newlifex/newlife.cube

Trust tier 2
  • community
LLM review pending
Source check pending

Checking that the SKILL.md file is still in the repository.

使用 @newlifex/cube-vue 的 Section 机制覆盖/扩展页面组件。 当用户说"覆盖页面"、"扩展页面"、"自定义组件"、"修改框架组件"时使用。 Section 机制允许在不修改框架源码的情况下,覆盖搜索栏、表格、操作按钮等页面区块。

Install

npx vskill@latest install newlifex/newlife.cube/cube-page-override

SKILL.md

@newlifex/cube-vue 页面覆盖 (Section)

什么时候用

当用户需要修改/覆盖框架默认组件(如搜索栏、表格、分页),又不希望修改框架源码时使用。

Section 机制原理

┌─────────────────────────────────────────────────┐
│ 框架组件 │
│ ┌─────────┐ ┌─────────┐ ┌─────────────────┐ │
│ │ Header │ │ Content │ │ Footer │ │
│ └─────────┘ └─────────┘ └─────────────────┘ │
│ ↑ ↑ ↑ │
│ │ │ │ │
│ ┌───┴───┐ ┌───┴───┐ ┌───┴───┐ │
│ │Section│ │Section│ │Section│ │
│ │覆盖 │ │覆盖 │ │覆盖 │ │
│ └───────┘ └───────┘ └───────┘ │
└─────────────────────────────────────────────────┘

命名规则

规则说明
大写开头文件名必须以大写字母开头,如 ListSearchBar.vue
PascalCase多个单词时首字母都大写,如 UserDetailHeader.vue
禁止小写index.vue、form.vue 等小写开头的文件不会被扫描

常用 Section 覆盖点

Section 名称覆盖位置用途
ListSearchBar.vue列表页面搜索栏自定义搜索条件
ListToolbar.vue列表工具栏添加自定义按钮
TableColumns.vue表格列配置修改列定义
FormFields.vue表单字段自定义表单控件
DetailHeader.vue详情页头部自定义详情头部
Pagination.vue分页组件自定义分页样式

创建 Section 组件

示例:覆盖列表页搜索栏

1. 在应用的 views 目录下创建

apps/<app-name>/src/views/
└── User/
├── index.vue # 列表主页面
└── ListSearchBar.vue # 搜索栏覆盖组件

2. 编写 Section 组件

vue
<template>
<div class="custom-search-bar">
<el-row :gutter="16">
<el-col :span="8">
<el-input
v-model="searchForm.name"
placeholder="请输入用户名"
clearable
/>
</el-col>
<el-col :span="8">
<el-select v-model="searchForm.status" placeholder="请选择状态">
<el-option label="启用" :value="1" />
<el-option label="禁用" :value="0" />
</el-select>
</el-col>
<el-col :span="8">
<el-button type="primary" @click="handleSearch">搜索</el-button>
<el-button @click="handleReset">重置</el-button>
<el-button type="success" @click="handleExport">导出</el-button>
</el-col>
</el-row>
</div>
</template>
<script setup lang="ts">
import { ref, reactive } from 'vue';
// 搜索表单
const searchForm = reactive({
name: '',
status: undefined as number | undefined,
});
// 搜索事件 - 触发父组件刷新
const emit = defineEmits<{
search: [form: typeof searchForm];
reset: [];
}>();
function handleSearch() {
emit('search', searchForm);
}
function handleReset() {
searchForm.name = '';
searchForm.status = undefined;
emit('reset');
}
function handleExport() {
// 自定义导出逻辑
console.log('导出数据');
}
</script>
<style scoped>
.custom-search-bar {
padding: 16px;
background: var(--el-bg-color);
border-radius: var(--el-border-radius-base);
}
</style>
示例:覆盖工具栏
vue
<template>
<div class="custom-toolbar">
<el-space>
<el-button type="primary" @click="handleAdd">
<el-icon><Plus /></el-icon>
新增用户
</el-button>
<el-button @click="handleBatchImport">
<el-icon><Upload /></el-icon>
批量导入
</el-button>
<el-button type="danger" @click="handleBatchDelete">
<el-icon><Delete /></el-icon>
批量删除
</el-button>
</el-space>
</div>
</template>
<script setup lang="ts">
import { Plus, Upload, Delete } from '@element-plus/icons-vue';
function handleAdd() {
// 新增逻辑
}
function handleBatchImport() {
// 批量导入逻辑
}
function handleBatchDelete() {
// 批量删除逻辑
}
</script>
<style scoped>
.custom-toolbar {
padding: 12px 16px;
border-bottom: 1px solid var(--el-border-color-lighter);
}
</style>

红线 / 禁止自行发挥

以下为历史踩坑固化的强制约束,落实时严格照办,禁止凭记忆或"想当然"自行发挥:
  1. Section 文件名必须 PascalCase 大写开头:ListSearchBar.vue/ListToolbar.vue 合法;index.vue/form.vue/listSearchBar.vue 不被扫描(Vite 插件只收大写开头文件,且排除 index.vue)。命名错 = 覆盖不生效且无明显报错。
  2. Section 只能覆盖框架预设的覆盖点:先用「常用 Section 覆盖点」表确认框架有对应槽位,再写组件;不要臆造不存在的 Section 名。
  3. 样式规范(硬约束):Section 组件里也禁止硬编码色值、禁止私占 --cube-layout-*、禁止在 scoped style 覆盖 --el-*、禁止定义任何自定义 CSS 变量;统一用 --el-* token(如本技能示例中的 .custom-search-bar/.custom-toolbar 已改为 var(--el-bg-color)、var(--el-border-color-lighter) 等)。
  4. 不要手写路由注册 Section:Section 由 initApp() 的 registerPageSections() 自动注册(虚拟模块 virtual:@newlifex/cube-vue-sections),不要在 routes.ts/main.ts 里手动引入。
  5. 与父组件通信只允许 `defineEmits` 约定事件:不要直接改父组件内部状态,按示例用 search/reset/refresh/open 等事件回传。

与父组件通信

Section 组件通过 defineEmits 与父组件通信:

typescript
// 定义事件
const emit = defineEmits<{
search: [form: object];
reset: [];
refresh: [];
open: [id: number];
}>();
// 触发事件
emit('search', searchForm);
emit('reset');
emit('refresh');
emit('open', 123);

自动注册

Vite 插件会自动扫描并注册 Section 组件:

  1. 插件在构建时扫描 views/ 目录
  2. 收集所有以大写字母开头的 .vue 文件
  3. 通过 virtual:@newlifex/cube-vue-sections 虚拟模块导出
  4. initApp() 时自动调用 registerPageSections() 注册

调试 Section

确认 Section 是否生效:

  1. 打开浏览器开发者工具
  2. 在 Vue Devtools 中查看 pageSections 状态
  3. 或检查控制台输出的 Section 注册信息

限制

  • Section 组件只能覆盖框架预设的覆盖点
  • 需要先确认框架是否有对应的覆盖点
  • 组件名称必须严格遵守大写开头规则

示例:完整覆盖用户列表页

apps/<app-name>/src/views/User/
├── index.vue # 主页面(由后端路由提供)
├── ListSearchBar.vue # 覆盖搜索栏
├── ListToolbar.vue # 覆盖工具栏
└── TableColumns.vue # 覆盖表格列(如果支持)

Security

  • Security scanPassed, 100 of 100Pattern checks on the skill's files.
  • Model reviewNot runA model review is scheduled for the next rescan.

Quality evaluation

  • Task evaluationNot runNo evaluation yet. Run one in Skill Studio.

Source

Popularity

Repository stars
629
Repository forks
167
7-day trend score
0

Stars and forks are for the whole GitHub repository, not this skill alone. Not refreshed yet.

Works with

Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.

  • Claude Code
  • Cursor
  • GitHub Copilot
  • Windsurf
  • Codex
  • Gemini CLI
  • Cline
  • Amp
  • Roo Code
  • Goose
  • Continue
  • Kilo Code
  • Junie
  • Trae
  • OpenHands
  • Qwen Code
  • AI Agent
  • Tabnine Chat
  • Sourcegraph Cody
  • Amazon Q
  • Firebase Genkit
  • Sweep
  • Devin
  • Phind
  • Mentat
  • Claude Desktop
  • Aider
  • GPT Pilot
  • Plandex
  • bolt.new
  • v0
  • Replit Agent
  • Anse
  • TypingMind
  • BetterChatGPT
  • LibreChat
  • Warp AI
  • Pieces
  • Fig AI
Embed badge
vskill VERIFIED badge
[![vskill VERIFIED](https://verified-skill.com/api/v1/skills/newlifex/newlife.cube/cube-page-override/badge)](https://verified-skill.com/skills/newlifex/newlife.cube/cube-page-override)

Something wrong with this skill or its page? Tell us.