欢迎来到冉冉博客的技术教程。今天分享深入Nuxt.js的实战经验,这些都是我在网站编程过程中总结的最佳实践。
一、Vue 3 组合式 API 深度应用
Vue 3 的 Composition API 是现代前端开发的核心技能。掌握组合式函数的设计模式,能写出更易维护、更易测试的代码。冉冉博客的前端项目全部迁移到 Vue 3,开发效率提升显著。
1.1 组合式函数设计模式
import { ref, computed, watch, onMounted } from 'vue'
export function useUser() {
const user = ref(null)
const isLoggedIn = computed(() => !!user.value)
async function login(credentials) {
user.value = await api.post('/auth/login', credentials)
localStorage.setItem('token', user.value.token)
}
function logout() {
user.value = null
localStorage.removeItem('token')
}
onMounted(async () => {
const token = localStorage.getItem('token')
if (token) {
user.value = await api.get('/user/me')
}
})
return { user, isLoggedIn, login, logout }
}
export function useFetch(url, options = {}) {
const data = ref(null)
const error = ref(null)
const isLoading = ref(false)
const fetchData = async (params = {}) => {
isLoading.value = true
try {
data.value = await api.get(url, { ...options, params })
} catch (e) {
error.value = e
} finally {
isLoading.value = false
}
}
return { data, error, isLoading, refetch: fetchData }
}
1.2 Pinia 状态管理
import { defineStore } from 'pinia'
export const useBlogStore = defineStore('blog', {
state: () => ({
articles: [],
currentArticle: null,
filters: { category: null, tag: null, page: 1 }
}),
getters: {
publishedArticles: (state) =>
state.articles.filter(a => a.status === 'published'),
totalPages: (state) => Math.ceil(state.articles.length / 10)
},
actions: {
async fetchArticles() {
this.articles = await api.get('/articles')
},
async fetchArticle(id) {
this.currentArticle = await api.get("/articles/" + id)
},
setFilter(key, value) {
this.filters[key] = value
this.filters.page = 1
}
},
persist: true
})
二、TypeScript 高级类型系统
TypeScript 让 JavaScript 开发更安全、更高效。掌握高级类型技巧,能在编译阶段发现大量潜在 bug。
2.1 泛型与条件类型
function first(arr: T[]): T | undefined {
return arr[0]
}
function longest(a: T, b: T): T {
return a.length > b.length ? a : b
}
type IsArray = T extends any[] ? true : false
type Unwrap = T extends Promise ? U : T
type User = { id: number; name: string; email: string }
type CreateUser = Omit
type UserPreview = Pick
type PartialUser = Partial
2.2 类型守卫与类型推断
function isString(value: unknown): value is string {
return typeof value === 'string'
}
type Shape = Circle | Square | Triangle
function area(shape: Shape): number {
if (shape.kind === 'circle') return Math.PI * shape.radius ** 2
else if (shape.kind === 'square') return shape.side ** 2
else return 0.5 * shape.base * shape.height
}
三、响应式布局与 CSS 工程化
现代 CSS 提供了强大的布局能力。掌握 Flexbox、Grid 和 CSS 变量,能快速构建任何复杂布局。
3.1 CSS Grid 布局
.blog-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 2rem;
}
.app-layout {
display: grid;
grid-template-areas:
"header header header"
"sidebar main aside"
"footer footer footer";
grid-template-columns: 200px 1fr 200px;
min-height: 100vh;
}
.card {
display: grid;
grid-template-rows: subgrid;
grid-row: span 3;
}
3.2 CSS 变量与主题系统
:root {
--color-primary: #3b82f6;
--color-text: #1f2937;
--color-bg: #ffffff;
--space-1: 0.25rem;
--space-4: 1rem;
--radius-md: 0.5rem;
}
@media (prefers-color-scheme: dark) {
:root {
--color-text: #f3f4f6;
--color-bg: #111827;
}
}
.button {
background: var(--color-primary);
padding: var(--space-2) var(--space-4);
}
四、Webpack/Vite 构建优化
构建工具的配置直接影响应用性能。掌握构建优化技巧,能显著减少打包体积和提升加载速度。
4.1 Vite 配置优化
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
export default defineConfig({
plugins: [vue()],
build: {
target: 'es2015',
minify: 'terser',
rollupOptions: {
output: {
manualChunks: {
'vendor': ['vue', 'vue-router', 'pinia'],
'utils': ['lodash-es', 'dayjs']
}
}
}
}
})
4.2 代码分割与懒加载
const routes = [
{ path: '/', component: () => import('./views/Home.vue') },
{ path: '/article/:id', component: () => import('./views/Article.vue') }
]
const HeavyChart = defineAsyncComponent({
loader: () => import('./HeavyChart.vue'),
loadingComponent: LoadingSpinner,
errorComponent: ErrorDisplay,
delay: 200,
timeout: 3000
})
五、自动化测试与代码质量
测试是保证代码质量的最后一道防线。掌握单元测试、集成测试和 E2E 测试的合理分层,能显著提升代码可靠性。
5.1 Vitest 单元测试
import { describe, it, expect, vi } from 'vitest'
import { mount } from '@vue/test-utils'
import ArticleCard from './ArticleCard.vue'
describe('ArticleCard.vue', () => {
it('renders title and content', () => {
const wrapper = mount(ArticleCard, {
props: { title: '测试文章', content: '测试内容', views: 100 }
})
expect(wrapper.find('.title').text()).toBe('测试文章')
})
it('formats views correctly', () => {
const wrapper = mount(ArticleCard, { props: { views: 1234 } })
expect(wrapper.find('.views').text()).toBe('1.2k')
})
})
5.2 Playwright E2E 测试
import { test, expect } from '@playwright/test'
test.describe('博客文章', () => {
test.beforeEach(async ({ page }) => {
await page.goto('/')
})
test('文章列表加载正常', async ({ page }) => {
await expect(page.locator('.article-card')).toHaveCount(10)
})
test('移动端响应式布局', async ({ page }) => {
await page.setViewportSize({ width: 375, height: 667 })
await expect(page.locator('.mobile-menu')).toBeVisible()
})
})
通过本文的学习,相信你已经掌握了深入Nuxt.js的核心要点。冉冉博客会持续分享更多实用技术教程,欢迎持续关注。
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END
















暂无评论内容