用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
直接命令不会经过审查 Prompt;运行前请先检查来源。
npx skills add https://github.com/GeorgeDoors888/GB-Power-Market-JJ --skill vue3-antdesignvue命令会保持在同一行。复制前请横向滚动并检查完整内容。
想先保存到本地?可下载 SkillsMP 当前能够提供的文件。
超级简历 WonderCV 出品,3000 万用户信赖。简历分析、段落改写、JD 岗位匹配、自动匹配职位、PDF 导出、AI 求职导师(面试准备/薪资谈判/职业规划/多版本简历策略)。 触发条件:用户提供简历、要求简历点评/打分/反馈、希望改写某个简历部分、 希望将简历与岗位 JD 匹配、咨询求职建议或面试准备,或提到 CV/简历/求职。 不触发条件:用户讨论普通写作(非简历)、询问其他文档, 或讨论与求职和职业发展无关的话题。
Order food/drinks (点餐) on an Android device paired as an OpenClaw node. Uses in-app menu and cart; add goods, view cart, submit order (demo, no real payment).
调用久吾智能体API进行文本或文件分析处理。支持两种调用方式:(1) 文本内容分析 - 传入name(智能体名称)、docno(文档编号)、content(文本内容);(2) 文件分析 - 传入name、docno和files(文件列表)进行智能评审。适用于合同评审、需求评审、文档审查等场景。当用户要求评审合同、分析条款、审查文档、需求评审、合同条款分析、或需要对文本和文件进行AI智能分析时触发。
基于 SOC 职业分类
正在显示 SKILL.md
| name | Vue3+AntDesignVue组件封装 |
| description | 用于封装基于 Vue 3 + Ant Design Vue 的通用业务组件,提供标准化组件封装模板和最佳实践。 |
ComponentName/ ├── index.vue ├── types.js(可选) ├── composables/ ├── components/ └── index.js
<template>
<div class="base-card-container">
<a-card :loading="loading">
<template #title>
<div class="card-header">
<span>{{ title }}</span>
<div class="header-actions">
<slot name="header-actions" />
</div>
</div>
</template>
<div class="card-content">
<slot />
</div>
<div v-if="showFooter" class="card-footer">
<slot name="footer">
<a-button @click="handleCancel">取消</a-button>
<a-button type="primary" :loading="submitLoading" @click="handleSubmit">
确定
</a-button>
</slot>
</div>
</a-card>
</div>
</template>
<script setup>
import { ref, computed, watch } from 'vue';
const props = defineProps({
title: { type: String, default: '' },
loading: { type: Boolean, default: false },
showFooter: { type: Boolean, default: true },
submitLoading: { type: Boolean, default: false },
data: { type: Object, default: () => ({}) }
});
const emit = defineEmits(['update:loading', 'submit', 'cancel', 'change']);
const internalLoading = ref(false);
const actualLoading = computed({
get: () => props.loading ?? internalLoading.value,
set: (val) => {
internalLoading.value = val;
emit('update:loading', val);
}
});
const handleSubmit = async () => {
try {
actualLoading.value = true;
emit('submit', props.data);
} finally {
actualLoading.value = false;
}
};
const handleCancel = () => {
emit('cancel');
};
watch(
() => props.data,
(val) => emit('change', val),
{ deep: true }
);
defineExpose({
loading: actualLoading,
handleSubmit,
handleCancel
});
</script>
<style lang="less" scoped>
.base-card-container {
width: 100%;
.card-header {
display: flex;
justify-content: space-between;
align-items: center;
}
.header-actions {
display: flex;
gap: 8px;
}
.card-footer {
display: flex;
justify-content: flex-end;
gap: 8px;
margin-top: 16px;
border-top: 1px solid var(--ant-border-color-split);
padding-top: 12px;
}
}
</style>
三、表单组件(DynamicForm)
<template>
<div class="dynamic-form-container">
<a-form
ref="formRef"
:model="formData"
:label-col="{ span: 6 }"
:wrapper-col="{ span: 18 }"
>
<a-row :gutter="16">
<a-col
v-for="field in fields"
:key="field.prop"
:span="field.span || 24"
>
<a-form-item :label="field.label" :name="field.prop" :rules="field.rules">
<!-- input -->
<a-input
v-if="field.type === 'input'"
v-model:value="formData[field.prop]"
:placeholder="field.placeholder"
@change="e => handleChange(field.prop, e.target.value)"
/>
<!-- select -->
<a-select
v-else-if="field.type === 'select'"
v-model:value="formData[field.prop]"
:options="field.options"
@change="val => handleChange(field.prop, val)"
/>
<!-- date -->
<a-date-picker
v-else-if="field.type === 'date'"
v-model:value="formData[field.prop]"
style="width: 100%"
@change="val => handleChange(field.prop, val)"
/>
<!-- slot -->
<slot
v-else
:name="`field-${field.prop}`"
:value="formData[field.prop]"
:onChange="val => handleChange(field.prop, val)"
/>
</a-form-item>
</a-col>
</a-row>
</a-form>
<div v-if="showActions" class="form-actions">
<a-button @click="handleReset">重置</a-button>
<a-button type="primary" :loading="loading" @click="handleSubmit">
{{ submitText }}
</a-button>
</div>
</div>
</template>
<script setup>
import { reactive, ref, watch } from 'vue';
const props = defineProps({
fields: { type: Array, required: true },
modelValue: { type: Object, default: () => ({}) },
showActions: { type: Boolean, default: true },
submitText: { type: String, default: '提交' },
loading: Boolean
});
const emit = defineEmits(['update:modelValue', 'submit', 'reset', 'change']);
const formRef = ref();
const formData = reactive({});
const init = () => {
props.fields.forEach(f => {
formData[f.prop] = props.modelValue[f.prop] ?? '';
});
};
const handleChange = (prop, val) => {
formData[prop] = val;
emit('update:modelValue', { ...formData });
emit('change', prop, val);
};
const handleSubmit = async () => {
await formRef.value.validate();
emit('submit', { ...formData });
};
const handleReset = () => {
formRef.value.resetFields();
emit('reset');
};
watch(() => props.modelValue, val => Object.assign(formData, val), { deep: true, immediate: true });
init();
</script>
<style lang="less" scoped>
.dynamic-form-container {
.form-actions {
display: flex;
justify-content: center;
gap: 12px;
margin-top: 16px;
}
}
</style>
四、表格组件(DataTable)
<template>
<div class="data-table-container">
<!-- toolbar -->
<div class="toolbar" v-if="showToolbar">
<div><slot name="toolbar-left" /></div>
<div>
<slot name="toolbar-right" />
<a-button size="small" @click="emit('refresh')">刷新</a-button>
</div>
</div>
<!-- table -->
<a-table
:columns="innerColumns"
:data-source="data"
:loading="loading"
:row-key="rowKey"
:pagination="false"
>
<template
v-for="col in columns"
#[col.prop]="{ record, index }"
v-if="col.slot"
>
<slot :name="col.prop" :row="record" :index="index" />
</template>
<template #operation="{ record }">
<a-button type="link" @click="emit('edit', record)">编辑</a-button>
<a-button type="link" danger @click="emit('delete', record)">删除</a-button>
</template>
</a-table>
<!-- pagination -->
<a-pagination
v-if="showPagination"
v-model:current="currentPage"
v-model:pageSize="pageSize"
:total="total"
show-size-changer
style="margin-top: 16px; text-align: right"
@change="val => emit('current-change', val)"
/>
</div>
</template>
<script setup>
import { computed } from 'vue';
const props = defineProps({
data: Array,
columns: Array,
loading: Boolean,
rowKey: { type: String, default: 'id' },
showToolbar: { type: Boolean, default: true },
showPagination: { type: Boolean, default: true },
currentPage: Number,
pageSize: Number,
total: Number
});
const emit = defineEmits([
'refresh',
'edit',
'delete',
'current-change',
'update:currentPage',
'update:pageSize'
]);
const currentPage = computed({
get: () => props.currentPage,
set: val => emit('update:currentPage', val)
});
const pageSize = computed({
get: () => props.pageSize,
set: val => emit('update:pageSize', val)
});
const innerColumns = computed(() => {
return [
...props.columns.map(col => ({
title: col.label,
dataIndex: col.prop,
key: col.prop,
customRender: col.slot ? undefined : ({ text }) => text ?? '-'
})),
{
title: '操作',
key: 'operation',
slots: { customRender: 'operation' }
}
];
});
</script>
<style lang="less" scoped>
.data-table-container {
.toolbar {
display: flex;
justify-content: space-between;
margin-bottom: 12px;
}
}
</style>
五、使用示例
<template>
<DataTable
:data="list"
:columns="columns"
:total="total"
v-model:currentPage="page"
v-model:pageSize="pageSize"
@refresh="loadData"
>
<template #status="{ row }">
<a-tag :color="row.status ? 'green' : 'red'">
{{ row.status ? '启用' : '禁用' }}
</a-tag>
</template>
</DataTable>
</template>