Vue3 基础教程

Vue3 基础教程

Vue3 是目前 Vue 生态的主流版本,基于 Composition API 重构,带来了更好的性能、更强的类型支持和更灵活的代码组织方式。本教程从环境搭建、核心语法到高级特性,全方位覆盖 Vue3 核心知识点,助你从入门到精通。

一、环境搭建

1. 前置条件

确保已安装 Node.js,可参考Nodejs基础教程(推荐 LTS 版本,v16+),验证方式:

bash 复制代码
node -v  # 输出版本号即安装成功
npm -v

2. 创建 Vue3 项目(Vite 脚手架)

Vite 是 Vue 官方推荐的构建工具,比 Webpack 更快,步骤如下:

bash 复制代码
# 1. 创建项目(npm/yarn/pnpm 均可,推荐 npm)
npm create vite@latest my-vue3-project -- --template vue

# 2. 进入项目目录
cd my-vue3-project

# 3. 安装依赖
npm install

# 4. 启动开发服务器
npm run dev

启动后访问终端提示的地址(如 http://127.0.0.1:5173/),即可看到 Vue3 初始页面。

3. 项目目录结构解析

plaintext 复制代码
my-vue3-project/
├── node_modules/       # 依赖包
├── public/             # 静态资源(不会被打包)
├── src/                # 核心源码目录
│   ├── assets/         # 静态资源(图片、样式,会被打包)
│   ├── components/     # 自定义组件
│   ├── App.vue         # 根组件
│   └── main.js         # 入口文件
├── .gitignore          # git 忽略配置
├── index.html          # 入口 HTML
├── package.json        # 项目配置/依赖
└── vite.config.js      # Vite 配置文件

二、Vue3 核心基础

1. 模板语法

Vue3 模板语法与 Vue2 基本一致,核心是「数据绑定」和「指令」。

(1)插值表达式
vue 复制代码
<template>
  <!-- 文本插值 -->
  <div>{{ message }}</div>
  
  <!-- 表达式插值(支持简单 JS 表达式) -->
  <div>{{ count + 1 }}</div>
  <div>{{ isShow ? '显示' : '隐藏' }}</div>
  
  <!-- 原始 HTML(慎用,防止 XSS) -->
  <div v-html="htmlContent"></div>
</template>

<script setup>
// Vue3 推荐 <script setup> 语法糖
const message = 'Hello Vue3!';
const count = 99;
const isShow = true;
const htmlContent = '<h1>Vue3 标题</h1>';
</script>
(2)指令
指令 作用 示例
v-bind 绑定属性(简写 : <img :src="imgUrl">
v-on 绑定事件(简写 @ <button @click="handleClick">
v-model 双向数据绑定 <input v-model="username">
v-if/v-else 条件渲染 <div v-if="isLogin">已登录</div>
v-for 列表渲染 <li v-for="item in list" :key="item.id">{{ item.name }}</li>
v-show 显示 / 隐藏(CSS 切换) <div v-show="isShow">显示</div>

示例:指令综合使用

vue 复制代码
<template>
  <!-- 条件渲染 -->
  <div v-if="role === 'admin'">管理员</div>
  <div v-else>普通用户</div>

  <!-- 列表渲染 -->
  <ul>
    <li v-for="item in userList" :key="item.id">
      {{ item.name }} - {{ item.age }}岁
    </li>
  </ul>

  <!-- 双向绑定 + 事件绑定 -->
  <input v-model="inputValue" placeholder="输入内容" />
  <button @click="handleSubmit">提交</button>

  <!-- 样式绑定 -->
  <div :class="{ active: isActive }" :style="{ color: textColor }">样式绑定</div>
</template>

<script setup>
const role = 'admin';
const userList = [
  { id: 1, name: '张三', age: 20 },
  { id: 2, name: '李四', age: 22 }
];
const inputValue = '';
const handleSubmit = () => {
  alert('提交内容:' + inputValue);
};
const isActive = true;
const textColor = 'red';
</script>

<style scoped>
.active {
  font-weight: bold;
}
</style>

2. Composition API(组合式 API)

Vue3 核心升级点,替代 Vue2 的 Options API,解决「代码碎片化」问题,核心 API 如下:

(1)setup 语法糖(核心)

<script setup> 是 Vue3 推荐写法,无需手动导出,代码更简洁:

  • 变量 / 函数直接在模板中使用
  • 生命周期钩子前缀加 on(如 onMounted
  • 组件导入后直接使用
(2)响应式数据

Vue3 提供两种核心响应式 API:refreactive

API 适用场景 访问方式
ref 基本类型(String/Number) .value(脚本中)
reactive 引用类型(Object/Array) 直接访问属性

示例:响应式数据

vue 复制代码
<template>
  <div>
    <p>计数(ref):{{ count }}</p>
    <button @click="count++">+1</button>

    <p>用户名(reactive):{{ user.name }}</p>
    <button @click="updateName">修改名字</button>
  </div>
</template>

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

// 基本类型响应式
const count = ref(0);

// 引用类型响应式
const user = reactive({
  name: '张三',
  age: 20
});

// 修改 reactive 数据
const updateName = () => {
  user.name = '李四';
};
</script>
(3)计算属性(computed)

基于响应式数据派生新值,缓存结果,依赖变化时自动更新:

vue 复制代码
<template>
  <div>
    <p>原始价格:{{ price }}</p>
    <p>折扣价格:{{ discountPrice }}</p>
    <p>总价:{{ totalPrice }}</p>
  </div>
</template>

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

const price = ref(100);
const count = ref(3);

// 只读计算属性
const discountPrice = computed(() => {
  return price.value * 0.8;
});

// 可写计算属性
const totalPrice = computed({
  get() {
    return discountPrice.value * count.value;
  },
  set(newValue) {
    price.value = newValue / count.value / 0.8;
  }
});

// 测试可写
// totalPrice.value = 240; // 会触发 set,price 变为 100
</script>
(4)侦听器(watch /watchEffect)

监听响应式数据变化,执行副作用逻辑。

API 特点
watch 显式指定监听源,可获取新旧值,惰性执行
watchEffect 自动收集依赖,立即执行,无法获取旧值

示例:侦听器

vue 复制代码
<template>
  <div>
    <input v-model="name" placeholder="输入名字" />
    <input v-model="user.age" type="number" placeholder="输入年龄" />
  </div>
</template>

<script setup>
import { ref, reactive, watch, watchEffect } from 'vue';

const name = ref('张三');
const user = reactive({ age: 20 });

// 监听 ref 数据
watch(name, (newVal, oldVal) => {
  console.log('名字变化:', oldVal, '→', newVal);
});

// 监听 reactive 单个属性
watch(() => user.age, (newVal) => {
  console.log('年龄变为:', newVal);
});

// 监听多个源
watch([name, () => user.age], ([newName, newAge]) => {
  console.log('名字:', newName, '年龄:', newAge);
});

// watchEffect(自动收集依赖)
watchEffect(() => {
  console.log('watchEffect:', name.value, user.age);
});
</script>
(5)生命周期钩子

Vue3 生命周期钩子需从 vue 导入,且在 <script setup> 中使用:

Vue2 钩子 Vue3 钩子(setup 中) 触发时机
beforeCreate - setup 中代码等效于此阶段
created - setup 中代码等效于此阶段
beforeMount onBeforeMount 组件挂载前
mounted onMounted 组件挂载完成(DOM 可用)
beforeUpdate onBeforeUpdate 组件更新前
updated onUpdated 组件更新完成
beforeUnmount onBeforeUnmount 组件卸载前
unmounted onUnmounted 组件卸载完成

示例:生命周期

vue 复制代码
<template>
  <div>生命周期示例</div>
</template>

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

onMounted(() => {
  console.log('组件挂载完成,可操作 DOM');
});

onUpdated(() => {
  console.log('组件更新完成');
});

onUnmounted(() => {
  console.log('组件卸载完成,清理定时器/事件');
});
</script>

3. 组件开发

Vue3 组件开发更灵活,支持全局组件和局部组件,核心是「Props 传值」和「事件派发」。

(1)组件定义与使用

步骤 1:创建子组件(src/components/Hello.vue)

vue 复制代码
<template>
  <div class="hello">
    <h2>{{ title }}</h2>
    <p>{{ content }}</p>
  </div>
</template>

<script setup>
// 定义 Props
const props = defineProps({
  title: {
    type: String,
    required: true, // 必填
    default: '默认标题' // 默认值(非必填时生效)
  },
  content: {
    type: String,
    default: '默认内容'
  }
});
</script>

<style scoped>
.hello {
  padding: 20px;
  border: 1px solid #eee;
}
</style>

步骤 2:在父组件中使用

vue 复制代码
<template>
  <div>
    <!-- 传入 Props -->
    <Hello title="Vue3 组件" content="组件通信示例" />
  </div>
</template>

<script setup>
// 导入组件(自动局部注册)
import Hello from './components/Hello.vue';
</script>
(2)组件通信
通信方式 适用场景 实现方式
Props 父 → 子 子组件 defineProps 接收
自定义事件 子 → 父 子组件 emit,父组件 @监听
provide/inject 跨层级(爷 → 孙) 父组件 provide,子组件 inject
Pinia/Vuex 全局状态 全局仓库管理(下文详解)

示例:自定义事件(子 → 父)

vue 复制代码
<!-- 子组件(Child.vue) -->
<template>
  <button @click="handleClick">向父组件传值</button>
</template>

<script setup>
// 定义可触发的事件
const emit = defineEmits(['sendData']);

const handleClick = () => {
  // 触发事件并传参
  emit('sendData', { id: 1, name: '子组件数据' });
};
</script>

<!-- 父组件 -->
<template>
  <Child @sendData="receiveData" />
  <p>子组件传来的数据:{{ childData.name }}</p>
</template>

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

const childData = ref({});

// 接收子组件数据
const receiveData = (data) => {
  childData.value = data;
};
</script>

示例:provide/inject(跨层级)

vue 复制代码
<!-- 父组件 -->
<template>
  <Child />
</template>

<script setup>
import { provide } from 'vue';
import Child from './components/Child.vue';

// 提供数据
provide('theme', 'dark');
provide('userInfo', { name: '张三', age: 20 });
</script>

<!-- 孙组件(GrandChild.vue) -->
<template>
  <div>
    <p>主题:{{ theme }}</p>
    <p>用户:{{ userInfo.name }}</p>
  </div>
</template>

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

// 注入数据
const theme = inject('theme', 'light'); // 第二个参数是默认值
const userInfo = inject('userInfo');
</script>

4. 路由(Vue Router)

Vue Router 是 Vue 官方路由工具,用于实现单页应用(SPA)的页面跳转。

(1)安装
bash 复制代码
npm install vue-router@4 # Vue3 对应 Router4 版本
(2)配置路由(src/router/index.js)
javascript 复制代码
import { createRouter, createWebHistory } from 'vue-router';
// 导入页面组件
import Home from '../views/Home.vue';
import About from '../views/About.vue';
import User from '../views/User.vue';

// 路由规则
const routes = [
  {
    path: '/',
    name: 'Home',
    component: Home
  },
  {
    path: '/about',
    name: 'About',
    component: About
  },
  {
    path: '/user/:id', // 动态路由
    name: 'User',
    component: User
  }
];

// 创建路由实例
const router = createRouter({
  history: createWebHistory(import.meta.env.BASE_URL), // 历史模式
  routes
});

export default router;
(3)在入口文件注册路由(src/main.js)
javascript 复制代码
import { createApp } from 'vue';
import App from './App.vue';
import router from './router'; // 导入路由

const app = createApp(App);
app.use(router); // 注册路由
app.mount('#app');
(4)使用路由
vue 复制代码
<!-- App.vue -->
<template>
  <div>
    <!-- 路由链接 -->
    <router-link to="/">首页</router-link>
    <router-link to="/about">关于</router-link>
    <router-link to="/user/100">用户100</router-link>

    <!-- 路由出口(匹配的组件渲染在这里) -->
    <router-view />
  </div>
</template>

<!-- User.vue(获取动态路由参数) -->
<template>
  <div>用户ID:{{ $route.params.id }}</div>
</template>

<script setup>
// 也可通过组合式 API 获取路由
import { useRoute, useRouter } from 'vue-router';

const route = useRoute(); // 当前路由信息
const router = useRouter(); // 路由实例

// 编程式导航
const goHome = () => {
  router.push('/');
};

console.log('用户ID:', route.params.id);
</script>

5. 状态管理(Pinia)

Pinia 是 Vue 官方推荐的状态管理工具,替代 Vuex,更简洁、支持 TypeScript,核心是「仓库(Store)」。

(1)安装
bash 复制代码
npm install pinia
(2)创建 Pinia 实例(src/main.js)
javascript 复制代码
import { createApp } from 'vue';
import { createPinia } from 'pinia';
import App from './App.vue';

const app = createApp(App);
app.use(createPinia()); // 注册 Pinia
app.mount('#app');
(3)创建仓库(src/stores/counter.js)
javascript 复制代码
import { defineStore } from 'pinia';

// 定义仓库(第一个参数是仓库唯一标识)
export const useCounterStore = defineStore('counter', {
  // 状态(类似 data)
  state: () => ({
    count: 0,
    msg: 'Pinia 示例'
  }),

  // 计算属性(类似 computed)
  getters: {
    doubleCount: (state) => state.count * 2
  },

  // 方法(类似 methods,支持异步)
  actions: {
    increment() {
      this.count++;
    },
    decrement() {
      this.count--;
    },
    async asyncIncrement() {
      await new Promise(resolve => setTimeout(resolve, 1000));
      this.count++;
    }
  }
});
(4)使用仓库
vue 复制代码
<template>
  <div>
    <p>计数:{{ counterStore.count }}</p>
    <p>双倍计数:{{ counterStore.doubleCount }}</p>
    <button @click="counterStore.increment">+1</button>
    <button @click="counterStore.decrement">-1</button>
    <button @click="counterStore.asyncIncrement">异步+1</button>
  </div>
</template>

<script setup>
import { useCounterStore } from '../stores/counter';

// 获取仓库实例
const counterStore = useCounterStore();

// 也可解构(需用 storeToRefs 保持响应式)
// import { storeToRefs } from 'pinia';
// const { count, doubleCount } = storeToRefs(counterStore);
// const { increment } = counterStore;
</script>

三、Vue3 高级特性

1. 自定义指令

封装通用 DOM 操作,如自动聚焦、权限控制等。

(1)定义全局指令(src/main.js)
javascript 复制代码
import { createApp } from 'vue';
import App from './App.vue';

const app = createApp(App);

// 自定义指令:v-focus(自动聚焦)
app.directive('focus', {
  // 指令挂载到元素时触发
  mounted(el) {
    el.focus();
  }
});

app.mount('#app');
(2)定义局部指令
vue 复制代码
<template>
  <input v-focus />
  <div v-color="'red'">自定义颜色</div>
</template>

<script setup>
// 局部指令:v-color
const vColor = {
  mounted(el, binding) {
    el.style.color = binding.value;
  }
};
</script>

2. 异步组件

按需加载组件,优化首屏加载速度。

vue 复制代码
<template>
  <AsyncComponent />
</template>

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

// 定义异步组件
const AsyncComponent = defineAsyncComponent(() => {
  return import('./components/AsyncComponent.vue');
});
</script>

3. Teleport(瞬移)

将组件 DOM 渲染到指定位置(如 body 下),解决层级嵌套问题(如弹窗、提示框)

vue 复制代码
<template>
  <button @click="showModal = true">打开弹窗</button>
  
  <teleport to="body">
    <div class="modal" v-if="showModal">
      <div class="modal-content">
        <h3>弹窗内容</h3>
        <button @click="showModal = false">关闭</button>
      </div>
    </div>
  </teleport>
</template>

<script setup>
import { ref } from 'vue';
const showModal = ref(false);
</script>

<style scoped>
.modal {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(0,0,0,0.5);
  display: flex;
  justify-content: center;
  align-items: center;
}
.modal-content {
  background: white;
  padding: 20px;
  border-radius: 4px;
}
</style>

4. Suspense(悬念)

等待异步组件加载完成前显示占位内容,提升用户体验。

vue 复制代码
<template>
  <Suspense>
    <!-- 异步组件 -->
    <template #default>
      <AsyncComponent />
    </template>
    <!-- 加载中占位 -->
    <template #fallback>
      <div>加载中...</div>
    </template>
  </Suspense>
</template>

<script setup>
import { defineAsyncComponent } from 'vue';
const AsyncComponent = defineAsyncComponent(() => {
  return new Promise(resolve => {
    setTimeout(() => {
      resolve(import('./components/AsyncComponent.vue'));
    }, 2000);
  });
});
</script>

四、项目优化与部署

1. 性能优化

  • 路由懒加载:异步组件 + 路由拆分,减少首屏体积
  • 图片优化 :使用 vite-plugin-imagemin 压缩图片,懒加载图片
  • 组件缓存 :使用 keep-alive 缓存频繁切换的组件
  • 减少重渲染 :合理使用 computedshallowRef/shallowReactive 减少响应式开销

2. 打包构建

bash 复制代码
# 生产环境打包
npm run build

打包后的文件在 dist 目录,可直接部署到静态服务器(如 Nginx、Netlify、Vercel)。

3. 部署示例(Nginx)

nginx 复制代码
server {
  listen 80;
  server_name your-domain.com;
  root /path/to/dist; # 打包后的 dist 目录路径
  index index.html;

  # 解决路由刷新 404 问题
  location / {
    try_files $uri $uri/ /index.html;
  }
}

五、学习资源与进阶方向

1. 官方资源

2. 进阶方向

  • TypeScript 集成:Vue3 + TS 提升代码可维护性
  • 组件库开发:基于 Vue3 开发自定义组件库(如 Element Plus)
  • SSR 服务端渲染:Nuxt3(Vue3 生态的 SSR 框架)
  • 跨端开发:UniApp/Taro 基于 Vue3 开发多端应用(小程序 / APP/H5)
  • 状态管理进阶:Pinia 持久化、模块化设计

总结

Vue3 的核心是 Composition API,相比 Vue2 更灵活、更易维护。本教程覆盖了 Vue3 从环境搭建到高级特性的全量知识点,建议结合实战项目(如个人博客、电商后台)巩固学习。掌握基础后,可深入学习 TypeScript 集成、性能优化等进阶内容,成为 Vue3 资深开发者。

相关推荐
布局呆星2 小时前
Vue 3 事件处理与列表渲染---02
前端·javascript·vue.js
码界奇点2 小时前
基于Spring Boot和Vue的多通道支付网关系统设计与实现
vue.js·spring boot·后端·毕业设计·鸿蒙系统·源代码管理
星光一影2 小时前
同城搭子活动组局H5系统源码-伴伴搭子系统源码
vue.js·mysql·php·uniapp
未寒2 小时前
关于uni app vue2 和vue3 的区别
前端·javascript·vue.js·uni-app
chenhdowue2 小时前
vue 甘特图 vxe-gantt 任务里程碑和依赖线的使用
vue.js·甘特图·vxe-ui·vxe-gantt
麦麦大数据2 小时前
F059 vue+flask酒店对比系统
前端·vue.js·flask·携程·酒店对比·飞猪·同程
Violet_YSWY2 小时前
Vue import.meta.env 讲解
前端·javascript·vue.js
暴富暴富暴富啦啦啦2 小时前
实现自定义指令 v-scrollBar,用于动态显示/隐藏滚动条,提升用户体验
前端·javascript·vue.js
Mr.app3 小时前
Element-Plus 面包屑当前项样式以及处理最后一个元素
vue.js