Vue 3 完整应用开发与扩展教程

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 的基本使用。同时,我们也了解到参与社区和开源的重要性。希望你能将这些知识运用到自己的项目中,不断提升自己的技能!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值