Token导航 LogoToken导航

Agent Skill · 研究检索

vue3-ant-design-vue-component-skill(vue3 ANT 设计 Vue component 技能)

用于辅助前端页面、组件、样式和交互逻辑的开发与维护。它适合让 Agent 生成或审查 React、Next.js、Vue、Tailwind、CSS 等相关代码,整理组件结构,或定位布局和性能问题。使用时需要结合项目现有设计系统、路由和构建方式,避免只生成孤立片段;涉及页面改动时,应配合本地预览和构建检查确认视觉效果。

vue3-ant-design-vue-component-skill 是研究检索类 Agent Skill,可用宿主为 OpenClaw,通过ClawHub获取,权限为只读;许可证为 MIT-0,第三方扫描已通过,按安装量在研究检索类的 73,675 个 Skill 里排第 24,752。

总安装 3,934周安装 169GitHub Stars 公开资料未说明下载 1,379核验 2026-05-01

安装说明

本站只整理中文说明,不托管安装包,也不代用户安装。
GitHub
许可证
MIT-0
版本
1.0.0

安装方式

通过对话安装

复制提示词发给支持本地命令或 Skills 的 AI 助手,先确认命令和权限,再让它执行。

请帮我安装这个 Agent Skill:vue3-ant-design-vue-component-skill(vue3 ANT 设计 Vue component 技能)
来源仓库:https://github.com/94lfj/vue3-ant-design-vue-component-skill
安装命令:
openclaw skills install vue3-ant-design-vue-component-skill
安装前请先检查当前环境是否支持对应 CLI,并向我确认将要执行的命令、安装目录、联网范围和文件读写权限;确认后再执行。

命令行安装

复制命令到本机终端执行。该命令会通过 OpenClaw 从第三方来源获取 Skill;本站只展示命令,不托管安装包,也不自动执行。

ClawHubOpenClaw
openclaw skills install vue3-ant-design-vue-component-skill

这个 Skill 是做什么的

研究检索类 Skill 主要解决「找资料、核对事实、把来源整理清楚」的问题,通常会让助手先检索再总结。

用于封装基于 Vue 3 + Ant Design Vue 的通用业务组件,提供标准化组件封装模板和最佳实践。

上手步骤

4 步
  1. 1

    确认自己的宿主工具

    公开资料标注支持 OpenClaw;先确认自己用的是其中之一,再按对应工具的 Skills 目录放置。

  2. 2

    拿到安装命令

    可以直接复制的命令是 openclaw skills install vue3-ant-design-vue-component-skill;命令里的占位符换成自己的路径或密钥再执行。

  3. 3

    安装后重启宿主

    命令执行完要完全退出宿主工具再打开,让新装的 Skill 被重新扫描到,否则列表里可能看不到。

  4. 4

    按最小权限试用

    它标注为只读,先用只读任务试一次,确认行为符合预期再扩大使用范围。

常见问题

6 条

vue3-ant-design-vue-component-skill 怎么安装?

在终端执行 openclaw skills install vue3-ant-design-vue-component-skill。装完完全退出宿主工具再打开,让它重新扫描本地 Skill。

vue3-ant-design-vue-component-skill 支持哪些 AI 工具?

公开资料标注支持 OpenClaw。其他工具只要能读取本地 Skill 目录,一般也能手动放进去,但要自己确认触发方式是否一致。

vue3-ant-design-vue-component-skill 需要什么权限?

权限级别是只读。该 Skill 主要提供规则、说明或参考内容,本身偏只读;真正读写文件、联网或执行命令仍取决于宿主 Agent 的任务。

vue3-ant-design-vue-component-skill 是免费的吗?

来源标注的许可证是 MIT-0。本站不代收任何费用,也不托管安装包;能否商用、要不要署名,以许可证原文为准。

vue3-ant-design-vue-component-skill 用的人多吗?

公开数据是累计安装 3,934 次,近一周安装 169 次,下载 1,379 次。这些数字来自第三方目录统计,只能当作热度参考,不代表质量或安全性。

vue3-ant-design-vue-component-skill 安全吗?

第三方扫描结果为通过,但这只覆盖已知的静态检查项,不能替代自己读一遍源码和安装命令。

值得选的地方和要先想清楚的地方

值得选的地方

  • 专注 OpenClaw 一种宿主,触发方式和使用习惯不用来回切换。
  • 许可证明确为 MIT-0,商用和分发边界好判断。
  • 第三方扫描已通过,常见的高风险行为没有命中。
  • 标注为只读权限,试用阶段不容易误改本地文件。

先想清楚的地方

  • 第三方目录整理,版本更新和行为细节以来源仓库为准。

适不适合你

更适合

  • 已经在用 OpenClaw,想直接扩展它能力的人。
  • 需要处理研究检索类任务、又不想每次都手写提示词的人。
  • 需要许可证清楚、并且有第三方扫描结果的团队项目。

不太适合

  • 需要厂商级技术支持和 SLA 的生产系统。

研究检索类 Skill 对比

6 个同类
Skill总安装GitHub 星权限许可证扫描
find-skills

寻找技能 · Codex、Claude

31,199,81316,486操作浏览器MIT有提醒
self-improving-agent

自我改进 Agent · OpenClaw

16,464,0023,396接触敏感数据MIT-0通过
soultrace

灵魂追踪 · Codex、Claude

7,588,94412需要联网未明确有提醒
self-improving

自我完善 · OpenClaw

6,829,2841,046需要联网MIT-0通过
microsoft-foundry

微软代工厂 · Codex、Claude

6,614,144764调用外部服务未明确有提醒
vue3-ant-design-vue-component-skill

vue3 ANT 设计 Vue component 技能 · 本页

3,934—只读MIT-0通过

按安装量取同分类前几名;数字来自第三方目录统计,只作热度参考,不代表质量结论。

SKILL.md 原文

name
Vue3+AntDesignVue组件封装
description
用于封装基于 Vue 3 + Ant Design Vue 的通用业务组件,提供标准化组件封装模板和最佳实践。

一、核心规范

1. 技术栈

  • 框架:Vue 3.4+
  • UI库:Ant Design Vue
  • 语言:JavaScript
  • 样式:Less
  • 构建:Vite

2. 命名规范

  • 文件夹:kebab-case(search-form)
  • 组件名:PascalCase(SearchForm)
  • Props/Events:camelCase
  • 样式类:kebab-case(.search-form-container)

3. 文件结构

ComponentName/ ├── index.vue ├── types.js(可选) ├── composables/ ├── components/ └── index.js


二、基础组件模板(Card容器)

<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>

平台分布

OpenClaw

87.8%
按下载量换算1,211

安全审计

VirusTotal

通过

ClawScan

通过

Static analysis

通过

权限和风险

只读

该 Skill 主要提供规则、说明或参考内容,本身偏只读;真正读写文件、联网或执行命令仍取决于宿主 Agent 的任务。

安装前确认

本站仅展示第三方公开信息,不托管安装包,不提供自动安装或运行环境。安装前应自行审查源码、依赖和命令行为。目前只有一个公开来源,建议同时核对源仓库。

继续浏览同类 Skills