用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
直接命令不会经过审查 Prompt;运行前请先检查来源。
npx skills add https://github.com/JohnNuwan/EVA_CORE --skill vue命令会保持在同一行。复制前请横向滚动并检查完整内容。
想先保存到本地?可下载 SkillsMP 当前能够提供的文件。
正在显示 SKILL.md
基于 SOC 职业分类
| name | vue |
| description | Guide complet Vue 3 : Composition API, Pinia, Vue Router, Vite, Nuxt, composables, slots, testing, optimisation. |
| tags | ["vue","vue3","composition-api","pinia","vue-router","vite","nuxt","composables","slots","typescript","testing"] |
<script setup lang="ts">
import { ref, computed, watch, onMounted } from 'vue';
const count = ref(0);
const doubled = computed(() => count.value * 2);
watch(count, (newVal, oldVal) => console.log(`count: ${oldVal} → ${newVal}`));
onMounted(() => fetchData());
</script>
<template>
<button @click="count++">{{ count }} × 2 = {{ doubled }}</button>
</template>
export default { data() { return { count: 0 } }, computed: { doubled() { ... } } }
const count = ref(0); // .value pour accès individuel
const state = reactive({ x: 0, y: 0 }); // Accès direct propriétés
const obj = ref({ a: 1 }); // ref + objet = reactive interne
const list = shallowRef([...bigArray]); // Pas de tracking profond — meilleur perf
triggerRef(list); // Forcer la mise à jour
watchEffect(() => console.log(count.value)); // S'exécute immédiatement + réagit aux changements
// useCounter.ts
export function useCounter(initial = 0) {
const count = ref(initial);
const increment = () => count.value++;
return { count, increment };
}
v-if/v-else-if/v-else — rendu conditionnelv-show — toggle display CSSv-for — itération (:key obligatoire)v-model — two-way binding (.lazy, .number, .trim)v-on (@) — événementsv-once — rendu uniquev-memo — mémoïsation (Vue 3.2+)<script setup lang="ts">
const props = defineProps<{ name: string; age?: number }>();
const emit = defineEmits<{ update: [value: string] }>();
</script>
<template>
<div class="card">
<header><slot name="header" /></header>
<main><slot /></main>
<footer><slot name="footer" text="bonjour" /></footer>
</div>
</template>
export const useCounterStore = defineStore('counter', () => {
const count = ref(0);
const increment = () => count.value++;
return { count, increment };
});
const routes = [
{ path: '/', component: Home },
{ path: '/users/:id', component: UserView, props: true },
{ path: '/:pathMatch(.*)*', name: 'NotFound', component: NotFound },
];
router.beforeEach((to, from) => {
if (to.meta.requiresAuth && !isLoggedIn) return '/login';
});
/server/api/)useFetch, useAsyncData, useState<script setup lang="ts">
const { data: users } = await useFetch('/api/users');
</script>
import { mount } from '@vue/test-utils';
it('increments', async () => {
const wrapper = mount(Counter);
await wrapper.find('button').trigger('click');
expect(wrapper.text()).toContain('1');
});
v-memo — templates lourdsshallowRef — grandes listesdefineAsyncComponent — lazy loadingreactive() sans toRefs()v-for + v-if — ne pas utiliser ensemble:key avec id pour listes dynamiques