Vue 3 完整教程:从入门到项目开发
本文最后更新于177 天前,其中的信息可能已经过时,如有错误请发送邮件到big_fw@foxmail.com

这是一份从零基础到能独立开发项目的完整 Vue 3 教程。

这个教程假设你有 HTML、CSS 和 JavaScript(ES6+)基础。如果没有,先补齐这些。

教程分为四个阶段:入门基础、核心概念、进阶工具、项目实践。

全程使用组合式 API(Vue 3 推荐风格),因为它更灵活。每个部分有代码示例、解释和练习。

学习建议

  • 用 Vite 创建项目(npm create vue@latest),边学边敲代码。
  • 官方文档:https://cn.vuejs.org/(随时查阅)。
  • 时间估计:入门 2-3 天,核心 3-5 天,进阶 2-3 天,项目 1 周。
  • 环境:Node.js 18+,VS Code 编辑器(安装 Volar 插件)。

阶段 1: 入门基础(快速上手)

目标:创建第一个应用,理解 Vue 的核心——响应式和模板。

1.1 安装与项目创建

  • 用 Vite 创建项目(推荐,热重载快):
npm create vue@latest my-vue-app
cd my-vue-app
npm install
npm run dev

选择:Yes(TypeScript?No,先基础);Yes(JSX?No);Yes(Router?稍后);Yes(Pinia?稍后);No(Vitest?稍后);No(ESLint?稍后)。

  • 目录结构:
my-vue-app/
├── src/
│ ├── components/ # 组件
│ ├── App.vue # 根组件
│ └── main.js # 入口
├── public/ # 静态资源
└── package.json

练习:运行 npm run dev,浏览器打开 http://localhost:5173,看到默认页面。

1.2 第一个应用:Hello World

编辑 src/App.vue:

<template>
  <div>
    <h1>{{ message }}</h1>
    <button @click="updateMessage">更新消息</button>
  </div>
</template>

<script setup>
import { ref } from 'vue';

const message = ref('Hello Vue 3!');  // 响应式变量

const updateMessage = () => {
  message.value = '消息已更新!';  // 更新数据,UI 自动刷新
};
</script>

<style>
h1 { color: blue; }
</style>
  • 解释
    • <template>:HTML 模板,{{ }} 插值。
    • <script setup>:组合式 API 的简洁语法,自动暴露变量/函数到模板。
    • ref():创建响应式引用,.value 访问/修改值。
    • @click:事件绑定。
    • <style>:组件样式(默认全局,加 scoped 限制范围)。

练习:添加一个输入框,用 v-model 双向绑定 message。

1.3 模板语法基础

  • 文本插值:{{ expression }}(如 {{ count + 1 }})。
  • 属性绑定::src=”imageUrl”(v-bind 缩写)。
  • 条件渲染:
<p v-if="isVisible">显示内容</p> 
<p v-else>隐藏内容</p>
<template v-for="item in items" :key="item.id">
<li>{{ item.name }}</li>
</template>
  • 事件与方法:@click=”handler($event)”,$event 是事件对象。

练习:构建一个列表,渲染 3 个物品,用按钮切换显示/隐藏。

阶段 2: 核心概念(构建组件化应用)

目标:掌握组件、数据流和生命周期。

2.1 组件创建与通信

组件是 Vue 的核心:可复用 UI 块。

  • 创建组件:新建 src/components/Counter.vue:
<template>
  <div>
    <p>计数:{{ count }}</p>
    <button @click="$emit('increment')">+1</button>
  </div>
</template>

<script setup>
import { ref } from 'vue';
defineProps(['initialValue']);  // 接收父组件 props
defineEmits(['increment']);     // 声明事件

const count = ref(0);
</script>
  • 在父组件使用(App.vue)
<template>
  <Counter :initial-value="5" @increment="handleIncrement" />
  <p>父组件计数:{{ parentCount }}</p>
</template>

<script setup>
import { ref } from 'vue';
import Counter from './components/Counter.vue';

const parentCount = ref(0);
const handleIncrement = () => {
  parentCount.value++;
};
</script>

解释

  • defineProps():接收数据(单向流动)。
  • defineEmits():子向父通信。
  • :initial-value:props 绑定(响应式)。

插槽(Slots):组件内容分发。

<!-- 子组件 -->
<template>
  <div>
    <slot name="header"></slot>  <!-- 默认插槽 -->
    <slot></slot>                <!-- 具名插槽 -->
  </div>
</template>
<!-- 父使用 -->
<MyCard>
  <template #header>标题</template>
  <p>内容</p>
</MyCard>

练习:创建一个 TodoItem 组件,接收任务文本作为 props,用插槽自定义按钮。

2.2 响应式与计算属性

ref vs reactive

  • ref(primitive):基本类型(如 string、number)。
  • reactive(object):对象/数组(无需 .value)。
<script setup>
import { ref, reactive, computed } from 'vue';

const count = ref(0);
const user = reactive({ name: '张三', age: 25 });

const doubled = computed(() => count.value * 2);  // 计算属性,缓存优化
const fullName = computed(() => `${user.name} - ${user.age}岁`);
</script>
  • 监听器:watch(() => count.value, (newVal) => { … })。

练习:用 computed 计算 Todo 列表的完成率。

2.3 生命周期钩子

Vue 组件有 8 个钩子(组合式 API 用 onXxx):

钩子时机用例
onBeforeMount 模板编译前准备数据
onMounted挂载后发送 AJAX、DOM 操作
onUpdated数据更新后响应变化
onUnmounted卸载前清理资源

示例:

<script setup>
import { onMounted, onUnmounted } from 'vue';

let timer;
onMounted(() => {
  timer = setInterval(() => console.log('tick'), 1000);
});
onUnmounted(() => clearInterval(timer));
</script>

练习:在组件挂载时从 localStorage 加载数据,卸载时保存。

阶段 3: 进阶工具(构建真实应用)

目标:集成路由、状态管理和优化。

3.1 Vue Router(路由)

安装:npm install vue-router@4。

  • 配置 src/router/index.js:
import { createRouter, createWebHistory } from 'vue-router';
import Home from '../views/Home.vue';
import About from '../views/About.vue';

const routes = [
  { path: '/', component: Home },
  { path: '/about', component: About }
];

export default createRouter({
  history: createWebHistory(),
  routes
});
  • 在 main.js:
import { createApp } from 'vue';
import App from './App.vue';
import router from './router';

createApp(App).use(router).mount('#app');
  • 使用:<router-view />(渲染组件),<router-link to=”/about”>关于</router-link>。

练习:添加动态路由 /user/:id,用 params 获取 ID。

3.2 状态管理:Pinia

安装:npm install pinia。

  • 创建 Store src/stores/counter.js:
import { defineStore } from 'pinia';
import { ref } from 'vue';

export const useCounterStore = defineStore('counter', () => {
  const count = ref(0);
  const increment = () => count.value++;
  return { count, increment };
});
  • 使用
<script setup>
import { useCounterStore } from '../stores/counter';

const store = useCounterStore();
</script>
<template>
  <p>{{ store.count }}</p>
  <button @click="store.increment">+1</button>
</template>
  • 在 main.js:app.use(createPinia())。

练习:用 Pinia 管理全局 Todo 列表(添加/删除)。

3.3 构建与部署

  • 开发:npm run dev。
  • 构建:npm run build(生成 dist/ 文件夹)。
  • 部署:上传到 Vercel/Netlify,或用 serve -s dist 本地预览。
  • 优化:用 vite.config.js 配置代理、插件。

练习:构建项目,部署到 GitHub Pages。

阶段 4: 项目实践(Todo App)

目标:整合所有知识,构建一个完整 Todo 应用(带路由、状态管理)。

项目概述

  • 功能:添加/编辑/删除任务,标记完成,路由切换(首页/详情),持久化(localStorage)。
  • 架构:
    • App.vue:路由入口。
    • views/Home.vue:Todo 列表。
    • components/TodoItem.vue:单个任务。
    • stores/todos.js:状态管理。

步骤 1: 设置项目

用 Vite 创建,安装 Router 和 Pinia。

步骤 2: 创建 Store(stores/todos.js)

import { defineStore } from 'pinia';
import { ref } from 'vue';

export const useTodosStore = defineStore('todos', () => {
  const todos = ref([]);  // { id, text, completed }

  const addTodo = (text) => {
    todos.value.push({ id: Date.now(), text, completed: false });
  };

  const toggleTodo = (id) => {
    const todo = todos.value.find(t => t.id === id);
    if (todo) todo.completed = !todo.completed;
  };

  const deleteTodo = (id) => {
    todos.value = todos.value.filter(t => t.id !== id);
  };

  // 持久化
  const saveToLocal = () => localStorage.setItem('todos', JSON.stringify(todos.value));
  const loadFromLocal = () => {
    const saved = localStorage.getItem('todos');
    if (saved) todos.value = JSON.parse(saved);
  };

  return { todos, addTodo, toggleTodo, deleteTodo, saveToLocal, loadFromLocal };
});

步骤 3: TodoItem 组件(components/TodoItem.vue)

<template>
  <li :class="{ completed: todo.completed }">
    <input type="checkbox" v-model="todo.completed" @change="$emit('toggle', todo.id)" />
    <span>{{ todo.text }}</span>
    <button @click="$emit('delete', todo.id)">删除</button>
  </li>
</template>

<script setup>
defineProps(['todo']);
defineEmits(['toggle', 'delete']);
</script>

<style scoped>
.completed { text-decoration: line-through; }
li { display: flex; gap: 10px; }
</style>

步骤 4: Home 视图(views/Home.vue)

<template>
  <div>
    <h1>我的 Todo 列表</h1>
    <input v-model="newTodo" @keyup.enter="addTodo" placeholder="添加任务" />
    <ul>
      <TodoItem v-for="todo in store.todos" :key="todo.id" :todo="todo" @toggle="store.toggleTodo" @delete="store.deleteTodo" />
    </ul>
  </div>
</template>

<script setup>
import { ref } from 'vue';
import { useTodosStore } from '../stores/todos';
import TodoItem from '../components/TodoItem.vue';

const store = useTodosStore();
const newTodo = ref('');

const addTodo = () => {
  if (newTodo.value.trim()) {
    store.addTodo(newTodo.value);
    store.saveToLocal();
    newTodo.value = '';
  }
};

store.loadFromLocal();  // 加载数据
</script>

步骤 5: 路由与 App(router/index.js 和 App.vue)

  • Router 如 3.1 节,添加 { path: ‘/’, component: Home }。
  • App.vue:
<template>
  <router-view />
</template>
<script setup>
import { onMounted } from 'vue';
import { useTodosStore } from './stores/todos';

onMounted(() => {
  const store = useTodosStore();
  store.loadFromLocal();
  window.addEventListener('beforeunload', () => store.saveToLocal());
});
</script>

步骤 6: 测试与扩展

  • 运行 npm run dev,添加/操作任务,刷新页面数据保留。
  • 扩展:
    • 添加编辑功能(用 input 替换 span)。
    • 路由到任务详情页(/todo/:id)。
    • 用 Axios 连接后端 API(安装 npm i axios)。

练习:完成项目后,添加过滤(未完成/所有),部署到 Vercel。

如果你坚持学到现在,那么恭喜你,你已经可以使用VUE来开发中型项目了

接下来通过所学知识以及查阅资料完成以下内容:

TypeScript:重启项目选 Yes,类型安全。

测试:用 Vitest(npm i -D vitest),写单元测试。

UI 库:Element Plus 或 Ant Design Vue。

真实项目:博客系统、电商列表(用 GitHub 托管)。

勤加练习,坚持实践,下一个百万年薪程序员就是你了!

文末附加内容
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇