Vue 3 完整应用开发与扩展教程
前言
在前几阶段中,我们学习了 Vue 3 的基础知识,包括组件创建、状态管理和路由使用等。现在我们将进入一个新的阶段,深入探讨如何将这些知识应用于实际项目,以及如何扩展我们的技能。本文将指导你创建一个完整的应用(例如个人博客、Todo List 或电商平台),并涵盖服务端渲染(SSR)、测试、TypeScript、参与社区与开源等内容。
1. 综合项目开发
1.1 选定项目
我们将以 个人博客 为例,创建一个完整的应用。项目需求包括:
- 用户可以查看文章列表和单篇文章
- 用户可以添加、编辑和删除自己的文章
- 用户可以注册和登录
- 文章的评论功能
1.2 项目初始化
使用 Vue CLI 快速创建项目。
vue create my-blog
cd my-blog
选择 Vue 3 并适当配置路由、Vuex(状态管理)和其他需要的插件。
1.3 结构设计
项目结构设计:
src/
├── assets/
├── components/
│ ├── ArticleList.vue
│ ├── ArticleItem.vue
│ └── ArticleEditor.vue
├── pages/
│ ├── Home.vue
│ ├── Login.vue
│ ├── Register.vue
│ ├── Article.vue
│ └── NotFound.vue
├── router/
│ └── index.js
├── store/
│ ├── index.js
│ └── modules/
│ └── articles.js
├── App.vue
└── main.js
1.4 组件开发
1.4.1 ArticleList.vue
展示文章列表的组件。
<template>
<div>
<h1>文章列表</h1>
<ul>
<ArticleItem v-for="article in articles" :key="article.id" :article="article" />
</ul>
</div>
</template>
<script>
import ArticleItem from '../components/ArticleItem.vue';
import { mapState } from 'vuex';
export default {
components: {
ArticleItem,
},
computed: {
...mapState('articles', ['articles']),
},
created() {
this.$store.dispatch('articles/fetchArticles');
},
};
</script>
1.4.2 ArticleItem.vue
展示单篇文章的组件。
<template>
<li>
<router-link :to="{ name: 'article', params: { id: article.id } }">{{ article.title }}</router-link>
</li>
</template>
<script>
export default {
props: {
article: {
type: Object,
required: true,
},
},
};
</script>
1.4.3 ArticleEditor.vue
添加和编辑文章的组件。
<template>
<div>
<h1>{{ isEditing ? '编辑文章' : '新建文章' }}</h1>
<form @submit.prevent="submitArticle">
<input v-model="article.title" placeholder="标题" />
<textarea v-model="article.content" placeholder="内容"></textarea>
<button type="submit">{{ isEditing ? '保存' : '发布' }}</button>
</form>
</div>
</template>
<script>
import { mapActions } from 'vuex';
export default {
props: {
isEditing: {
type: Boolean,
default: false,
},
article: {
type: Object,
default: () => ({ title: '', content: '' }),
},
},
data() {
return {
article: { ...this.article },
};
},
methods: {
...mapActions('articles', ['createArticle', 'updateArticle']),
async submitArticle() {
if (this.isEditing) {
await this.updateArticle(this.article);
} else {
await this.createArticle(this.article);
}
this.$router.push({ name: 'home' });
},
},
};
</script>
1.5 路由配置
在 src/router/index.js
中配置路由。
import { createRouter, createWebHistory } from 'vue-router';
import Home from '../pages/Home.vue';
import Login from '../pages/Login.vue';
import Register from '../pages/Register.vue';
import Article from '../pages/Article.vue';
import NotFound from '../pages/NotFound.vue';
const routes = [
{ path: '/', name: 'home', component: Home },
{ path: '/login', name: 'login', component: Login },
{ path: '/register', name: 'register', component: Register },
{ path: '/article/:id', name: 'article', component: Article },
{ path: '/:catchAll(.*)', name: 'not-found', component: NotFound },
];
const router = createRouter({
history: createWebHistory(),
routes,
});
export default router;
1.6 状态管理
在 src/store/modules/articles.js
中管理文章数据。
import axios from 'axios';
const state = {
articles: [],
};
const mutations = {
setArticles(state, articles) {
state.articles = articles;
},
};
const actions = {
async fetchArticles({ commit }) {
const response = await axios.get('/api/articles');
commit('setArticles', response.data);
},
async createArticle({ dispatch }, article) {
await axios.post('/api/articles', article);
dispatch('fetchArticles');
},
async updateArticle({ dispatch }, article) {
await axios.put(`/api/articles/${article.id}`, article);
dispatch('fetchArticles');
},
};
const getters = {
articles: (state) => state.articles,
};
export default {
namespaced: true,
state,
mutations,
actions,
getters,
};
1.7 表单处理
在表单中处理用户输入和验证。
- 使用
v-model
进行数据绑定。 - 实现基本的输入验证和提示。
2. 服务端渲染(SSR)与 Nuxt.js
2.1 Nuxt.js 介绍
Nuxt.js 是一个基于 Vue.js 的框架,用于构建服务端渲染 (SSR) 应用程序。它可以帮助你轻松地实现路由、状态管理和服务端请求等功能。
2.2 创建 Nuxt 应用
使用以下命令创建一个新的 Nuxt 应用:
npx create-nuxt-app my-nuxt-blog
在初始化的时候选择适合自己需求的模块,例如 axios、vuex 等。
2.3 目录结构
Nuxt.js 的项目结构如下:
my-nuxt-blog/
├── assets/
├── components/
├── layouts/
├── pages/
├── plugins/
├── store/
├── nuxt.config.js
└── package.json
2.4 页面创建与数据获取
在 pages/index.vue
中创建主页,并获取文章数据。
<template>
<div>
<h1>文章列表</h1>
<ul>
<li v-for="article in articles" :key="article.id">
<nuxt-link :to="'/article/' + article.id">{{ article.title }}</nuxt-link>
</li>
</ul>
</div>
</template>
<script>
export default {
async asyncData({ $axios }) {
const { data } = await $axios.get('/api/articles');
return { articles: data };
},
};
</script>
2.5 路由定义
Nuxt.js 会自动通过 pages
目录生成路由,确保文件名符合路由规则。
2.6 SSR 优势
SSR 有助于提高搜索引擎优化(SEO)和首屏加载速度,使内容在服务端预渲染,客户浏览器得到完整的 HTML 页面。
3. 测试
3.1 单元测试
使用 Vue Test Utils 和 Jest 为 Vue 组件编写单元测试。
3.1.1 安装依赖
npm install --save-dev @vue/test-utils jest
3.1.2 编写测试
在 tests/unit
目录下创建测试文件,并编写测试用例。
import { mount } from '@vue/test-utils';
import ArticleItem from '@/components/ArticleItem.vue';
describe('ArticleItem.vue', () => {
it('renders article title', () => {
const article = { id: 1, title: 'Test Article' };
const wrapper = mount(ArticleItem, {
props: { article },
});
expect(wrapper.text()).toContain('Test Article');
});
});
3.2 端到端测试
使用 Cypress 实现端到端测试。
3.2.1 安装 Cypress
npm install --save-dev cypress
3.2.2 编写测试
在 cypress/integration
目录下创建测试文件。
describe('My Blog', () => {
it('loads the home page', () => {
cy.visit('/');
cy.contains('文章列表');
});
});
4. TypeScript 与 Vue
4.1 在 Vue 中使用 TypeScript
如果你想要在 Vue 3 中使用 TypeScript,可以在初始化项目时选择 TypeScript 选项。之后,可以在组件中添加类型注解。
<script lang="ts">
import { defineComponent } from 'vue';
export default defineComponent({
props: {
msg: {
type: String,
required: true,
},
},
});
</script>
4.2 类型系统与组件结合
使用 TypeScript 可以提供更好的类型安全和代码提示。你可以为状态、属性和事件定义类型,确保在开发阶段能及时发现潜在错误。
5. 参与社区与开源
5.1 加入 Vue.js 社区
参与 Vue 的相关论坛和社交媒体,如 Vue 论坛、Stack Overflow、Twitter 和 Discord,向他人学习并发布你的项目。
5.2 开源贡献
寻找 Vue.js 相关的开源项目,先从文档改进、Bug 修复开始,逐步深入 code review 和 feature 贡献。
5.3 学习资源
- Vue.js 官方文档:提供详尽的使用和开发教程。
- Nuxt.js 文档:深入了解 Nuxt.js 的使用方式和高级功能。
- 社区博客和视频:跟踪最新的开发动态。
结论
通过本文,我们创建了一个完整的 Vue 3 应用,实现了服务端渲染、测试与 TypeScript 的基本使用。同时,我们也了解到参与社区和开源的重要性。希望你能将这些知识运用到自己的项目中,不断提升自己的技能!