一键导入
nuxt-vue-patterns
Vue 3 + Nuxt 4 best practices for Mellumine: Composition API, auto-imports, TypeScript, SCSS, CSS custom properties, and component conventions.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Vue 3 + Nuxt 4 best practices for Mellumine: Composition API, auto-imports, TypeScript, SCSS, CSS custom properties, and component conventions.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
i18n management for Mellumine: key structure, naming conventions, both-locale rule, and translation quality guidelines. Use when adding or modifying translation entries.
Add a new plushie to the Mellumine collection: update data.ts and both locale files. Use when adding any new plushie to the site.
Manage translation entries in fr-FR.json and en-US.json. Use when adding, modifying, or reviewing i18n keys for pages, components, or images.
Vue 3 + Nuxt 4 conventions for this project: SFC structure, auto-imports, TypeScript, SCSS, CSS custom properties, components, and composables. Use when writing or reviewing any .vue file.
Add a new plushie entry to data.ts and both locale files. Use when the user provides a new plushie to add to the collection.
Reference and checklist for SEO metadata on any page. Use when writing, reviewing, or debugging useHead() and useSeoMeta() on any page.
| name | nuxt-vue-patterns |
| description | Vue 3 + Nuxt 4 best practices for Mellumine: Composition API, auto-imports, TypeScript, SCSS, CSS custom properties, and component conventions. |
This skill documents the Vue 3 / Nuxt 4 conventions used across Mellumine. Follow these patterns for all new code and when modifying existing files.
<template>
<!-- markup -->
</template>
<script setup lang="ts">
// imports (data utils and types — the only manual imports needed)
// definePageMeta
// composables
// reactive state
// computed properties
// functions
</script>
<style lang="scss" scoped>
/* styles */
</style>
Rules:
<script setup lang="ts"> — never Options API, never <script> without setuplang="scss" scoped on styles — never plain CSS, never unscopedNuxt auto-imports the following — adding a manual import is an error:
Vue reactivity: ref, computed, watch, watchEffect, reactive, readonly, toRef, toRefs
Nuxt composables: useI18n, useHead, useSeoMeta, useRoute, useRouter, useRuntimeConfig, useNuxtApp, useState, useFetch, useAsyncData, navigateTo, definePageMeta, useLocalePath
VueUse: all composables from @vueuse/nuxt (useIntersectionObserver, useMouse, etc.)
// Data utilities — NOT auto-imported
import { plushies } from '~/utils/data'
import { socials, supports, credits } from '~/utils/data'
// Types always require explicit import
import type { Plushie } from '~/types/content'
import type { SocialLink } from '~/types/content'
import type { ImageSource } from '~/types/content'
Always use <NuxtLinkLocale> for internal links:
<!-- ✅ Correct -->
<NuxtLinkLocale to="/about">À propos</NuxtLinkLocale>
<NuxtLinkLocale to="/plushies" class="btn">Peluches</NuxtLinkLocale>
<!-- ❌ Wrong — do not use localePath() in this project -->
<NuxtLink :to="localePath('/about')">À propos</NuxtLink>
Component <style> blocks use SCSS variables from app/styles/variables.scss, auto-injected via Vite additionalData:
<style lang="scss" scoped>
.my-element {
color: $aurora-1; /* ✅ purple #7c5cff */
color: $aurora-2; /* ✅ pink #ff8fd1 */
color: $aurora-3; /* ✅ cyan #5be0ff */
font-family: $font-display; /* ✅ Cormorant Garamond */
font-family: $font-sans; /* ✅ Quicksand */
z-index: $header-z-index; /* ✅ 100 */
color: var(--aurora-1); /* ❌ do not use CSS vars in <style> blocks */
}
</style>
Runtime CSS custom properties (--accent, --i, --header-height) remain valid only when the value is set dynamically per-element via inline styles or JavaScript.
For scroll-in animations, use the custom useReveal() composable:
const { el: myEl, visible: myVisible } = useReveal()
In the template:
<section
ref="myEl"
:class="['section', 'fade-in-up', { 'is-visible': myVisible }]">
...
</section>
<!-- Above-the-fold (hero) image — use fetchpriority -->
<img
src="/images/mellumine/mellumine-look.webp"
:alt="$t('pictures.mellumine_look.alt')"
:title="$t('pictures.mellumine_look.title')"
fetchpriority="high"
decoding="async"
width="640"
height="900" />
<!-- Below-the-fold image — use lazy loading -->
<img
src="/images/mellumine/mellumine-1.webp"
:alt="$t('pictures.mellumine_1.alt')"
:title="$t('pictures.mellumine_1.title')"
loading="lazy"
decoding="async"
width="600"
height="800" />
width and height to prevent layout shift:alt to an i18n key — never hardcode alt text:title to an i18n key — displays tooltip on hover// Typed data references
const items: Plushie[] = plushies
// Computed with type inference
const baseUrl = ref(runtimeConfig.public.i18n.baseUrl)
const canonicalUrl = computed(() => `${baseUrl.value}${route.path}`)
strict: true is enabled in tsconfig.json — no implicit any, use proper types.
<PlushieCard v-for="p in plushies" :key="p.id" :plushie="p" />
Handles multi-view display, thumbnails, view switching, description, and dimensions automatically.
<SocialCard v-for="s in socials" :key="s.id" :link="s" />
Auto-imported layout components — never import manually.
yarn lint # check
yarn lint:fix # auto-fix
Rules:
no-console: warn — remove debug logs before committing