vue-nuxt by martinholovsky/claude-skills-generator
npx skills add https://github.com/martinholovsky/claude-skills-generator --skill vue-nuxt文件组织 : 此技能采用分割结构。高级模式和安全示例请参阅
references/目录。
此技能提供使用 Vue 3 和 Nuxt 3 构建 JARVIS AI 助手用户界面的专业知识。它专注于采用安全优先的开发实践,创建响应式、高性能的 3D HUD 界面。
风险等级 : 中等 - 处理用户输入、渲染动态内容,存在潜在的 XSS 攻击向量
主要用例 :
<script setup> 以获得更好的 TypeScript 推断和代码组织ref() 和 reactive() 以防止状态损坏广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
| 包 | 版本 | 安全说明 |
|---|---|---|
| Vue | ^3.4.0 | 最新稳定版,改进了响应性 |
| Nuxt | ^3.12.4+ | 关键 : 修复了 CVE-2024-34344 RCE |
| @nuxt/devtools | ^1.3.9+ | 关键 : 修复了 CVE-2024-23657 |
| vite | ^5.0.0 | 最新版,包含安全补丁 |
{
"dependencies": {
"nuxt": "^3.12.4",
"vue": "^3.4.0",
"dompurify": "^3.0.6",
"isomorphic-dompurify": "^2.0.0"
},
"devDependencies": {
"@nuxt/devtools": "^1.3.9",
"eslint-plugin-vue": "^9.0.0",
"eslint-plugin-security": "^2.0.0"
}
}
<script setup lang="ts">
// ✅ 带验证的类型安全 props
interface Props {
hudData: HUDDisplayData
userId: string
}
const props = defineProps<Props>()
// ✅ 带类型化载荷的事件发射
const emit = defineEmits<{
'update:status': [status: string]
'command:execute': [command: JARVISCommand]
}>()
// ✅ 安全的 ref 初始化
const displayState = ref<HUDState>({
isActive: false,
securityLevel: 'standard'
})
</script>
<template>
<!-- ✅ 对用户内容使用 v-text 以防止 XSS -->
<div class="hud-panel">
<span v-text="props.hudData.title" />
</div>
</template>
// composables/useSanitize.ts
import DOMPurify from 'isomorphic-dompurify'
export function useSanitize() {
const sanitizeHTML = (dirty: string): string => {
// ✅ 对任何 HTML 内容进行严格净化
return DOMPurify.sanitize(dirty, {
ALLOWED_TAGS: ['b', 'i', 'em', 'strong', 'span'],
ALLOWED_ATTR: ['class']
})
}
const sanitizeText = (input: string): string => {
// ✅ 为纯文本剥离所有 HTML
return DOMPurify.sanitize(input, { ALLOWED_TAGS: [] })
}
return { sanitizeHTML, sanitizeText }
}
// server/api/jarvis/command.post.ts
import { z } from 'zod'
// ✅ 为命令验证定义严格模式
const commandSchema = z.object({
action: z.enum(['status', 'control', 'query']),
target: z.string().max(100).regex(/^[a-zA-Z0-9-_]+$/),
parameters: z.record(z.string()).optional()
})
export default defineEventHandler(async (event) => {
const body = await readBody(event)
// ✅ 根据模式验证输入
const result = commandSchema.safeParse(body)
if (!result.success) {
throw createError({
statusCode: 400,
message: '无效的命令格式' // ✅ 通用错误消息
})
}
// ✅ 处理已验证的命令
const command = result.data
// 绝不记录敏感数据
console.log(`处理命令: ${command.action}`)
return { success: true, commandId: generateSecureId() }
})
// nuxt.config.ts
export default defineNuxtConfig({
// ✅ 安全头部
routeRules: {
'/**': {
headers: {
'Content-Security-Policy': "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'",
'X-Content-Type-Options': 'nosniff',
'X-Frame-Options': 'DENY',
'X-XSS-Protection': '1; mode=block'
}
}
},
// ✅ 运行时配置 - 密钥保留在服务器端
runtimeConfig: {
apiSecret: process.env.API_SECRET, // 仅服务器端
public: {
apiBase: '/api' // 客户端可访问
}
},
// ✅ 在生产环境中禁用开发者工具
devtools: { enabled: process.env.NODE_ENV === 'development' }
})
<script setup lang="ts">
// components/HUDDisplay.vue
import { TresCanvas } from '@tresjs/core'
const props = defineProps<{
metrics: SystemMetrics
}>()
// ✅ 在渲染前验证指标
const validatedMetrics = computed(() => {
return {
cpu: Math.min(100, Math.max(0, props.metrics.cpu)),
memory: Math.min(100, Math.max(0, props.metrics.memory)),
status: sanitizeText(props.metrics.status)
}
})
</script>
<template>
<TresCanvas>
<HUDMetricsDisplay :data="validatedMetrics" />
</TresCanvas>
</template>
始终从编写定义预期行为的测试开始:
// tests/components/VoiceIndicator.test.ts
import { describe, it, expect } from 'vitest'
import { mount } from '@vue/test-utils'
import VoiceIndicator from '@/components/VoiceIndicator.vue'
describe('VoiceIndicator', () => {
it('默认显示空闲状态', () => {
const wrapper = mount(VoiceIndicator)
expect(wrapper.find('.indicator').classes()).toContain('idle')
expect(wrapper.text()).toContain('就绪')
})
it('激活时显示监听状态', async () => {
const wrapper = mount(VoiceIndicator, {
props: { isListening: true }
})
expect(wrapper.find('.indicator').classes()).toContain('listening')
expect(wrapper.find('.pulse-animation').exists()).toBe(true)
})
it('按下退出键时发出取消事件', async () => {
const wrapper = mount(VoiceIndicator, {
props: { isListening: true }
})
await wrapper.trigger('keydown.escape')
expect(wrapper.emitted('cancel')).toBeTruthy()
})
})
仅编写足够使测试通过的代码:
<script setup lang="ts">
const props = defineProps<{ isListening?: boolean }>()
const emit = defineEmits<{ 'cancel': [] }>()
const handleKeydown = (e: KeyboardEvent) => {
if (e.key === 'Escape') emit('cancel')
}
</script>
<template>
<div
class="indicator"
:class="isListening ? 'listening' : 'idle'"
@keydown="handleKeydown"
tabindex="0"
>
<span v-if="!isListening">就绪</span>
<div v-else class="pulse-animation" />
</div>
</template>
测试通过后,在不改变行为的前提下改进代码质量。每次重构后重新运行测试。
# 提交前运行所有验证步骤
npx vitest run # 单元测试
npx eslint . --ext .vue,.ts # 代码检查
npx nuxi typecheck # 类型检查
npm run build # 构建验证
// ❌ 错误 - 每次渲染时在模板中重新计算
<template>
<div>{{ items.filter(i => i.active).length }} 个活跃</div>
</template>
// ✅ 正确 - 缓存直到依赖项改变
const activeCount = computed(() => items.value.filter(i => i.active).length)
<template>
<div>{{ activeCount }} 个活跃</div>
</template>
// ❌ 错误 - 对大型 3D 数据进行深度响应式
const meshData = ref<MeshData>({ vertices: new Float32Array(100000), ... })
// ✅ 正确 - 浅层响应式,手动触发
const meshData = shallowRef<MeshData>({ vertices: new Float32Array(100000), ... })
// 显式触发更新
meshData.value = { ...newData }
triggerRef(meshData)
// ❌ 错误 - 所有组件预先加载
import HeavyChart from '@/components/HeavyChart.vue'
// ✅ 正确 - 仅在需要时加载
const HeavyChart = defineAsyncComponent(() =>
import('@/components/HeavyChart.vue')
)
// 带加载状态
const HeavyChart = defineAsyncComponent({
loader: () => import('@/components/HeavyChart.vue'),
loadingComponent: LoadingSpinner,
delay: 200
})
<!-- ❌ 错误 - 任何更改时重新渲染所有项目 -->
<div v-for="item in items" :key="item.id">
<ExpensiveComponent :data="item" />
</div>
<!-- ✅ 正确 - 如果项目未更改则跳过重新渲染 -->
<div v-for="item in items" :key="item.id" v-memo="[item.id, item.updated]">
<ExpensiveComponent :data="item" />
</div>
<script setup lang="ts">
import { useVirtualList } from '@vueuse/core'
const { list, containerProps, wrapperProps } = useVirtualList(
items,
{ itemHeight: 50 }
)
</script>
<template>
<!-- ✅ 仅渲染可见项目 -->
<div v-bind="containerProps" class="h-[400px] overflow-auto">
<div v-bind="wrapperProps">
<div v-for="{ data, index } in list" :key="index">
{{ data.name }}
</div>
</div>
</div>
</template>
// ❌ 错误 - 每次按键都会触发
watch(searchQuery, async (query) => {
results.value = await searchAPI(query)
})
// ✅ 正确 - 防抖以减少 API 调用
import { watchDebounced } from '@vueuse/core'
watchDebounced(
searchQuery,
async (query) => {
results.value = await searchAPI(query)
},
{ debounce: 300 }
)
// 使用手动防抖的替代方案
watch(searchQuery, useDebounceFn(async (query) => {
results.value = await searchAPI(query)
}, 300))
| CVE | 严重性 | 描述 | 缓解措施 |
|---|---|---|---|
| CVE-2024-34344 | 高 | 通过测试组件的 Nuxt RCE | 更新到 Nuxt 3.12.4+ |
| CVE-2024-23657 | 高 | 开发者工具路径遍历/RCE | 更新开发者工具到 1.3.9+ |
| CVE-2023-3224 | 严重 | 开发服务器代码注入 | 更新到 Nuxt 3.4.4+,绝不暴露开发服务器 |
参见 : references/security-examples.md 获取详细的缓解代码
| OWASP 类别 | 风险 | 缓解策略 |
|---|---|---|
| A01 失效的访问控制 | 高 | 服务器端路由守卫、中间件认证 |
| A03 注入 | 高 | 使用 Zod 进行输入验证、参数化查询 |
| A05 安全配置错误 | 中 | CSP 头部、安全的 nuxt.config |
| A07 XSS | 高 | v-text 指令、DOMPurify 净化 |
// ❌ 危险 - 直接使用 v-html 与用户输入
<div v-html="userMessage" />
// ✅ 安全 - 净化的 HTML 或纯文本
<div v-html="sanitizeHTML(userMessage)" />
<span v-text="userMessage" />
// middleware/auth.ts
export default defineNuxtRouteMiddleware((to) => {
const { authenticated } = useAuthState()
if (!authenticated.value && to.meta.requiresAuth) {
return navigateTo('/login')
}
})
// tests/security/xss.test.ts
import { describe, it, expect } from 'vitest'
import { mount } from '@vue/test-utils'
import HUDPanel from '@/components/HUDPanel.vue'
describe('XSS 预防', () => {
it('应净化恶意输入', () => {
const wrapper = mount(HUDPanel, {
props: {
title: '<script>alert("xss")</script>Hello'
}
})
expect(wrapper.html()).not.toContain('<script>')
expect(wrapper.text()).toContain('Hello')
})
})
// tests/components/HUDDisplay.test.ts
describe('HUDDisplay', () => {
it('验证指标边界', () => {
const wrapper = mount(HUDDisplay, {
props: {
metrics: { cpu: 150, memory: -10, status: 'active' }
}
})
// 应将值限制在有效范围内
expect(wrapper.vm.validatedMetrics.cpu).toBe(100)
expect(wrapper.vm.validatedMetrics.memory).toBe(0)
})
})
<!-- ❌ 危险 - XSS 漏洞 -->
<div v-html="userProvidedContent" />
<!-- ✅ 安全 - 净化的内容 -->
<div v-html="sanitizeHTML(userProvidedContent)" />
<!-- ✅ 最佳 - 当不需要 HTML 时使用纯文本 -->
<span v-text="userProvidedContent" />
// ❌ 危险 - 公共配置中的密钥
runtimeConfig: {
public: {
apiKey: process.env.API_KEY // 暴露给客户端!
}
}
// ✅ 安全 - 密钥保留在服务器端
runtimeConfig: {
apiKey: process.env.API_KEY, // 仅服务器端
public: {
apiBase: '/api'
}
}
// ❌ 危险 - 仅客户端验证
const handleSubmit = () => {
if (isValidEmail(email.value)) {
$fetch('/api/subscribe', { body: { email: email.value } })
}
}
// ✅ 安全 - 服务器端验证
// server/api/subscribe.post.ts
export default defineEventHandler(async (event) => {
const body = await readBody(event)
const result = emailSchema.safeParse(body)
if (!result.success) {
throw createError({ statusCode: 400, message: '无效的邮箱' })
}
// 处理已验证的邮箱
})
// ❌ 错误 - 每次访问都创建新数组
const filtered = computed(() => {
return items.value.filter(i => i.active).sort()
})
// ✅ 正确 - 使用稳定引用进行记忆化
const filtered = computed(() => {
const result = items.value.filter(i => i.active)
result.sort((a, b) => a.name.localeCompare(b.name))
return result
})
# 开发
npx nuxi dev --host # 绝不暴露给公共网络!
# 安全审计
npm audit --audit-level=high
npx nuxi typecheck
# 生产构建
npx nuxi build
// 状态管理
const state = useState<T>('key', () => initialValue)
// 运行时配置访问
const config = useRuntimeConfig()
// 路由导航
const router = useRouter()
await navigateTo('/path')
runtimeConfig.public 中没有密钥npm audit 显示无高/严重漏洞此 Vue/Nuxt 技能为构建 JARVIS AI 助手 HUD 界面提供了安全模式:
记住 : JARVIS HUD 处理敏感的系统数据。每个组件都必须将用户输入视为潜在恶意,并验证所有数据边界。
参考资料 :
references/advanced-patterns.md - 复杂组件模式references/security-examples.md - 详细的安全实现每周安装数
94
代码仓库
GitHub 星标数
29
首次出现
2026年1月20日
安全审计
安装于
codex74
gemini-cli74
opencode73
github-copilot70
cursor69
claude-code63
File Organization : This skill uses split structure. See
references/for advanced patterns and security examples.
This skill provides expertise for building the JARVIS AI Assistant user interface using Vue 3 and Nuxt 3. It focuses on creating responsive, performant 3D HUD interfaces with security-first development practices.
Risk Level : MEDIUM - Handles user input, renders dynamic content, potential XSS vectors
Primary Use Cases :
<script setup> for better TypeScript inference and code organizationref() and reactive() with proper typing to prevent state corruption| Package | Version | Security Notes |
|---|---|---|
| Vue | ^3.4.0 | Latest stable with improved reactivity |
| Nuxt | ^3.12.4+ | CRITICAL : Fixes CVE-2024-34344 RCE |
| @nuxt/devtools | ^1.3.9+ | CRITICAL : Fixes CVE-2024-23657 |
| vite | ^5.0.0 | Latest with security patches |
{
"dependencies": {
"nuxt": "^3.12.4",
"vue": "^3.4.0",
"dompurify": "^3.0.6",
"isomorphic-dompurify": "^2.0.0"
},
"devDependencies": {
"@nuxt/devtools": "^1.3.9",
"eslint-plugin-vue": "^9.0.0",
"eslint-plugin-security": "^2.0.0"
}
}
<script setup lang="ts">
// ✅ Type-safe props with validation
interface Props {
hudData: HUDDisplayData
userId: string
}
const props = defineProps<Props>()
// ✅ Emit events with typed payloads
const emit = defineEmits<{
'update:status': [status: string]
'command:execute': [command: JARVISCommand]
}>()
// ✅ Secure ref initialization
const displayState = ref<HUDState>({
isActive: false,
securityLevel: 'standard'
})
</script>
<template>
<!-- ✅ Use v-text for user content to prevent XSS -->
<div class="hud-panel">
<span v-text="props.hudData.title" />
</div>
</template>
// composables/useSanitize.ts
import DOMPurify from 'isomorphic-dompurify'
export function useSanitize() {
const sanitizeHTML = (dirty: string): string => {
// ✅ Strict sanitization for any HTML content
return DOMPurify.sanitize(dirty, {
ALLOWED_TAGS: ['b', 'i', 'em', 'strong', 'span'],
ALLOWED_ATTR: ['class']
})
}
const sanitizeText = (input: string): string => {
// ✅ Strip all HTML for plain text
return DOMPurify.sanitize(input, { ALLOWED_TAGS: [] })
}
return { sanitizeHTML, sanitizeText }
}
// server/api/jarvis/command.post.ts
import { z } from 'zod'
// ✅ Define strict schema for command validation
const commandSchema = z.object({
action: z.enum(['status', 'control', 'query']),
target: z.string().max(100).regex(/^[a-zA-Z0-9-_]+$/),
parameters: z.record(z.string()).optional()
})
export default defineEventHandler(async (event) => {
const body = await readBody(event)
// ✅ Validate input against schema
const result = commandSchema.safeParse(body)
if (!result.success) {
throw createError({
statusCode: 400,
message: 'Invalid command format' // ✅ Generic error message
})
}
// ✅ Process validated command
const command = result.data
// Never log sensitive data
console.log(`Processing command: ${command.action}`)
return { success: true, commandId: generateSecureId() }
})
// nuxt.config.ts
export default defineNuxtConfig({
// ✅ Security headers
routeRules: {
'/**': {
headers: {
'Content-Security-Policy': "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'",
'X-Content-Type-Options': 'nosniff',
'X-Frame-Options': 'DENY',
'X-XSS-Protection': '1; mode=block'
}
}
},
// ✅ Runtime config - secrets stay server-side
runtimeConfig: {
apiSecret: process.env.API_SECRET, // Server only
public: {
apiBase: '/api' // Client accessible
}
},
// ✅ Disable devtools in production
devtools: { enabled: process.env.NODE_ENV === 'development' }
})
<script setup lang="ts">
// components/HUDDisplay.vue
import { TresCanvas } from '@tresjs/core'
const props = defineProps<{
metrics: SystemMetrics
}>()
// ✅ Validate metrics before rendering
const validatedMetrics = computed(() => {
return {
cpu: Math.min(100, Math.max(0, props.metrics.cpu)),
memory: Math.min(100, Math.max(0, props.metrics.memory)),
status: sanitizeText(props.metrics.status)
}
})
</script>
<template>
<TresCanvas>
<HUDMetricsDisplay :data="validatedMetrics" />
</TresCanvas>
</template>
Always start by writing tests that define expected behavior:
// tests/components/VoiceIndicator.test.ts
import { describe, it, expect } from 'vitest'
import { mount } from '@vue/test-utils'
import VoiceIndicator from '@/components/VoiceIndicator.vue'
describe('VoiceIndicator', () => {
it('displays idle state by default', () => {
const wrapper = mount(VoiceIndicator)
expect(wrapper.find('.indicator').classes()).toContain('idle')
expect(wrapper.text()).toContain('Ready')
})
it('shows listening state when active', async () => {
const wrapper = mount(VoiceIndicator, {
props: { isListening: true }
})
expect(wrapper.find('.indicator').classes()).toContain('listening')
expect(wrapper.find('.pulse-animation').exists()).toBe(true)
})
it('emits cancel event on escape key', async () => {
const wrapper = mount(VoiceIndicator, {
props: { isListening: true }
})
await wrapper.trigger('keydown.escape')
expect(wrapper.emitted('cancel')).toBeTruthy()
})
})
Write only enough code to make the tests pass:
<script setup lang="ts">
const props = defineProps<{ isListening?: boolean }>()
const emit = defineEmits<{ 'cancel': [] }>()
const handleKeydown = (e: KeyboardEvent) => {
if (e.key === 'Escape') emit('cancel')
}
</script>
<template>
<div
class="indicator"
:class="isListening ? 'listening' : 'idle'"
@keydown="handleKeydown"
tabindex="0"
>
<span v-if="!isListening">Ready</span>
<div v-else class="pulse-animation" />
</div>
</template>
After tests pass, improve code quality without changing behavior. Re-run tests after each refactor.
# Run all verification steps before committing
npx vitest run # Unit tests
npx eslint . --ext .vue,.ts # Linting
npx nuxi typecheck # Type checking
npm run build # Build verification
// ❌ BAD - Recalculates in template on every render
<template>
<div>{{ items.filter(i => i.active).length }} active</div>
</template>
// ✅ GOOD - Cached until dependencies change
const activeCount = computed(() => items.value.filter(i => i.active).length)
<template>
<div>{{ activeCount }} active</div>
</template>
// ❌ BAD - Deep reactivity on large 3D data
const meshData = ref<MeshData>({ vertices: new Float32Array(100000), ... })
// ✅ GOOD - Shallow reactivity, manual trigger
const meshData = shallowRef<MeshData>({ vertices: new Float32Array(100000), ... })
// Trigger update explicitly
meshData.value = { ...newData }
triggerRef(meshData)
// ❌ BAD - All components loaded upfront
import HeavyChart from '@/components/HeavyChart.vue'
// ✅ GOOD - Load only when needed
const HeavyChart = defineAsyncComponent(() =>
import('@/components/HeavyChart.vue')
)
// With loading state
const HeavyChart = defineAsyncComponent({
loader: () => import('@/components/HeavyChart.vue'),
loadingComponent: LoadingSpinner,
delay: 200
})
<!-- ❌ BAD - Re-renders all items on any change -->
<div v-for="item in items" :key="item.id">
<ExpensiveComponent :data="item" />
</div>
<!-- ✅ GOOD - Skip re-render if item unchanged -->
<div v-for="item in items" :key="item.id" v-memo="[item.id, item.updated]">
<ExpensiveComponent :data="item" />
</div>
<script setup lang="ts">
import { useVirtualList } from '@vueuse/core'
const { list, containerProps, wrapperProps } = useVirtualList(
items,
{ itemHeight: 50 }
)
</script>
<template>
<!-- ✅ Only renders visible items -->
<div v-bind="containerProps" class="h-[400px] overflow-auto">
<div v-bind="wrapperProps">
<div v-for="{ data, index } in list" :key="index">
{{ data.name }}
</div>
</div>
</div>
</template>
// ❌ BAD - Fires on every keystroke
watch(searchQuery, async (query) => {
results.value = await searchAPI(query)
})
// ✅ GOOD - Debounced to reduce API calls
import { watchDebounced } from '@vueuse/core'
watchDebounced(
searchQuery,
async (query) => {
results.value = await searchAPI(query)
},
{ debounce: 300 }
)
// Alternative with manual debounce
watch(searchQuery, useDebounceFn(async (query) => {
results.value = await searchAPI(query)
}, 300))
| CVE | Severity | Description | Mitigation |
|---|---|---|---|
| CVE-2024-34344 | HIGH | Nuxt RCE via test component | Update to Nuxt 3.12.4+ |
| CVE-2024-23657 | HIGH | Devtools path traversal/RCE | Update devtools to 1.3.9+ |
| CVE-2023-3224 | CRITICAL | Dev server code injection | Update to Nuxt 3.4.4+, never expose dev server |
See : references/security-examples.md for detailed mitigation code
| OWASP Category | Risk | Mitigation Strategy |
|---|---|---|
| A01 Broken Access Control | HIGH | Server-side route guards, middleware auth |
| A03 Injection | HIGH | Input validation with Zod, parameterized queries |
| A05 Security Misconfiguration | MEDIUM | CSP headers, secure nuxt.config |
| A07 XSS | HIGH | v-text directive, DOMPurify sanitization |
// ❌ DANGEROUS - Direct v-html with user input
<div v-html="userMessage" />
// ✅ SECURE - Sanitized HTML or plain text
<div v-html="sanitizeHTML(userMessage)" />
<span v-text="userMessage" />
// middleware/auth.ts
export default defineNuxtRouteMiddleware((to) => {
const { authenticated } = useAuthState()
if (!authenticated.value && to.meta.requiresAuth) {
return navigateTo('/login')
}
})
// tests/security/xss.test.ts
import { describe, it, expect } from 'vitest'
import { mount } from '@vue/test-utils'
import HUDPanel from '@/components/HUDPanel.vue'
describe('XSS Prevention', () => {
it('should sanitize malicious input', () => {
const wrapper = mount(HUDPanel, {
props: {
title: '<script>alert("xss")</script>Hello'
}
})
expect(wrapper.html()).not.toContain('<script>')
expect(wrapper.text()).toContain('Hello')
})
})
// tests/components/HUDDisplay.test.ts
describe('HUDDisplay', () => {
it('validates metric bounds', () => {
const wrapper = mount(HUDDisplay, {
props: {
metrics: { cpu: 150, memory: -10, status: 'active' }
}
})
// Should clamp values to valid range
expect(wrapper.vm.validatedMetrics.cpu).toBe(100)
expect(wrapper.vm.validatedMetrics.memory).toBe(0)
})
})
<!-- ❌ DANGEROUS - XSS vulnerability -->
<div v-html="userProvidedContent" />
<!-- ✅ SECURE - Sanitized content -->
<div v-html="sanitizeHTML(userProvidedContent)" />
<!-- ✅ BEST - Plain text when HTML not needed -->
<span v-text="userProvidedContent" />
// ❌ DANGEROUS - Secret in public config
runtimeConfig: {
public: {
apiKey: process.env.API_KEY // Exposed to client!
}
}
// ✅ SECURE - Secrets stay server-side
runtimeConfig: {
apiKey: process.env.API_KEY, // Server only
public: {
apiBase: '/api'
}
}
// ❌ DANGEROUS - Client-only validation
const handleSubmit = () => {
if (isValidEmail(email.value)) {
$fetch('/api/subscribe', { body: { email: email.value } })
}
}
// ✅ SECURE - Server-side validation
// server/api/subscribe.post.ts
export default defineEventHandler(async (event) => {
const body = await readBody(event)
const result = emailSchema.safeParse(body)
if (!result.success) {
throw createError({ statusCode: 400, message: 'Invalid email' })
}
// Process validated email
})
// ❌ BAD - Creates new array on every access
const filtered = computed(() => {
return items.value.filter(i => i.active).sort()
})
// ✅ GOOD - Memoized with stable reference
const filtered = computed(() => {
const result = items.value.filter(i => i.active)
result.sort((a, b) => a.name.localeCompare(b.name))
return result
})
# Development
npx nuxi dev --host # Never expose to public network!
# Security audit
npm audit --audit-level=high
npx nuxi typecheck
# Production build
npx nuxi build
// State management
const state = useState<T>('key', () => initialValue)
// Runtime config access
const config = useRuntimeConfig()
// Route navigation
const router = useRouter()
await navigateTo('/path')
runtimeConfig.publicnpm audit shows no high/critical vulnerabilitiesThis Vue/Nuxt skill provides secure patterns for building the JARVIS AI Assistant HUD interface:
Remember : The JARVIS HUD handles sensitive system data. Every component must treat user input as potentially malicious and validate all data boundaries.
References :
references/advanced-patterns.md - Complex component patternsreferences/security-examples.md - Detailed security implementationsWeekly Installs
94
Repository
GitHub Stars
29
First Seen
Jan 20, 2026
Security Audits
Gen Agent Trust HubFailSocketPassSnykPass
Installed on
codex74
gemini-cli74
opencode73
github-copilot70
cursor69
claude-code63
Azure PostgreSQL 无密码身份验证配置指南:Entra ID 迁移与访问管理
34,800 周安装
Vercel开发最佳实践:Next.js、React服务器组件与AI SDK部署指南
93 周安装
App Store Connect 版本说明生成器 - 自动本地化更新日志与SEO优化
93 周安装
公众号标题优化专家 | 技术/效率工具类内容创作者必备的AI标题诊断与生成工具
93 周安装
TanStack Query 最佳实践:React 服务器状态管理与 TypeScript 类型安全指南
93 周安装
Haskell专业开发技能:高级类型系统、函数式架构与并发编程最佳实践
93 周安装
EachLabs AI视频生成API:165+模型,文本/图像一键生成视频
93 周安装