深入理解Vue3核心概念,掌握多种开发环境搭建方式
Vue3是一个渐进式JavaScript框架,用于构建用户界面。它由尤雨溪(Evan You)创建,于2020年9月正式发布。Vue3在架构、性能、开发体验等方面都进行了重大改进。
渐进式框架意味着你可以根据项目需求逐步采用Vue3的功能:
革命性的代码组织方式,解决了Options API在复杂组件中的代码组织问题:
Vue3完全用TypeScript重写,提供一流的TypeScript开发体验。
核心机制:基于Proxy的响应式系统
| 特性 | Vue2(Object.defineProperty) | Vue3(Proxy) |
|---|---|---|
| 数组监听 | 需要特殊处理,无法监听索引变化 | 完美支持数组所有操作 |
| 对象新增属性 | 需要使用Vue.set | 自动监听新增属性 |
| 性能 | 递归遍历所有属性 | 惰性监听,按需响应 |
| 嵌套对象 | 深度递归,性能开销大 | 延迟代理,性能优化 |
// Vue3响应式核心原理示例
const reactive = (obj) => {
return new Proxy(obj, {
get(target, key) {
console.log(`读取属性: ${key}`)
return target[key]
},
set(target, key, value) {
console.log(`设置属性: ${key} = ${value}`)
target[key] = value
// 触发视图更新
return true
}
})
}
const state = reactive({ count: 0 })
state.count++ // 触发set拦截器
根据不同的使用场景,Vue3提供了多种环境搭建方式:
适用场景:快速原型开发、学习演示、简单的静态页面
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Vue3 CDN示例</title>
<!-- 引入Vue3 CDN -->
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
</head>
<body>
<div id="app">
<h1>{{ title }}</h1>
<p>计数器: {{ count }}</p>
<button @click="increment">点击+1</button>
</div>
<script>
// 从Vue全局对象中解构createApp
const { createApp } = Vue;
// 创建Vue应用实例
const app = createApp({
// 数据选项
data() {
return {
title: '我的第一个Vue3应用',
count: 0
}
},
// 方法选项
methods: {
increment() {
this.count++;
}
}
});
// 挂载到DOM元素
app.mount('#app');
</script>
</body>
</html>
适用场景:生产环境项目、需要构建优化的应用
# 使用npm(推荐)
npm create vue@latest
# 或者使用yarn
yarn create vue
# 或者使用pnpm
pnpm create vue
✔ Project name: my-vue-app # 项目名称
✔ Add TypeScript? No / Yes # 是否添加TypeScript支持
✔ Add JSX Support? No / Yes # 是否支持JSX语法
✔ Add Vue Router? No / Yes # 是否添加Vue Router路由
✔ Add Pinia? No / Yes # 是否添加Pinia状态管理
✔ Add Vitest? No / Yes # 是否添加Vitest测试框架
✔ Add ESLint? No / Yes # 是否添加ESLint代码检查
✔ Add Prettier? No / Yes # 是否添加Prettier代码格式化
# 进入项目目录
cd my-vue-app
# 安装依赖
npm install
# 启动开发服务器
npm run dev
适用场景:需要兼容Vue2项目、企业级复杂应用
# 全局安装Vue CLI
npm install -g @vue/cli
# 创建项目
vue create my-vue3-app
# 选择Vue3预设
? Please pick a preset:
Default ([Vue 3] babel, eslint)
Default ([Vue 2] babel, eslint)
Manually select features
| 特性 | Vite | Vue CLI |
|---|---|---|
| 启动速度 | 秒级启动(基于ESM) | 较慢(基于Webpack打包) |
| 热更新 | 极快(按需编译) | 较慢(全量打包) |
| 配置复杂度 | 简单,开箱即用 | 复杂,需要配置Webpack |
| 生态成熟度 | 较新,但发展迅速 | 成熟稳定 |
| 推荐场景 | 新项目、学习 | 企业级、复杂项目 |
创建一个完整的Vue3单文件应用,包含数据绑定、事件处理和计算属性:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Vue3计数器应用</title>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<style>
body { font-family: Arial, sans-serif; margin: 0; padding: 20px; }
.counter { text-align: center; margin-top: 50px; }
button { padding: 10px 20px; margin: 0 5px; font-size: 16px; }
.history { margin-top: 20px; }
</style>
</head>
<body>
<div id="app">
<div class="counter">
<h1>{{ title }}</h1>
<p>当前计数: <span style="font-size: 2em; color: #42b883;">{{ count }}</span></p>
<p>计数平方: {{ squaredCount }}</p>
<div>
<button @click="decrement" :disabled="count <= 0">-1</button>
<button @click="reset">重置</button>
<button @click="increment">+1</button>
</div>
<div class="history" v-if="history.length > 0">
<h3>操作历史</h3>
<ul>
<li v-for="(item, index) in history" :key="index">
{{ item.action }} - 结果: {{ item.value }}
</li>
</ul>
</div>
</div>
</div>
<script>
const { createApp } = Vue;
const app = createApp({
data() {
return {
title: 'Vue3计数器应用',
count: 0,
history: []
}
},
computed: {
squaredCount() {
return this.count * this.count;
}
},
methods: {
increment() {
this.count++;
this.addToHistory('增加', this.count);
},
decrement() {
if (this.count > 0) {
this.count--;
this.addToHistory('减少', this.count);
}
},
reset() {
this.count = 0;
this.addToHistory('重置', this.count);
},
addToHistory(action, value) {
this.history.unshift({
action,
value,
timestamp: new Date().toLocaleTimeString()
});
// 只保留最近5条记录
if (this.history.length > 5) {
this.history.pop();
}
}
}
});
app.mount('#app');
</script>
</body>
</html>
my-vue-app/
├── node_modules/ # 项目依赖包(自动生成)
├── public/ # 静态资源目录(不参与构建)
│ ├── favicon.ico # 网站图标
│ └── index.html # HTML模板(Vite会处理)
├── src/ # 源代码目录
│ ├── assets/ # 静态资源(图片、字体等)
│ ├── components/ # 可复用组件
│ ├── App.vue # 根组件(应用入口)
│ ├── main.js # 应用入口文件
│ └── style.css # 全局样式
├── .gitignore # Git忽略文件配置
├── index.html # 主HTML文件
├── package.json # 项目配置和依赖管理
├── package-lock.json # 依赖版本锁定文件
├── README.md # 项目说明文档
└── vite.config.js # Vite构建配置
import { createApp } from 'vue'
import App from './App.vue'
import './style.css'
// 创建Vue应用实例
const app = createApp(App)
// 可以在这里注册全局组件、插件等
// app.component('MyComponent', MyComponent)
// 挂载到DOM
app.mount('#app')
<template>
<div id="app">
<img alt="Vue logo" src="./assets/logo.png">
<HelloWorld msg="欢迎使用Vue3 + Vite" />
</div>
</template>
<script>
import HelloWorld from './components/HelloWorld.vue'
export default {
name: 'App',
components: {
HelloWorld
}
}
</script>
<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>
// settings.json
{
"vetur.validation.template": false,
"vetur.validation.script": false,
"vetur.validation.style": false,
"vetur.format.enable": false,
"vetur.useWorkspaceDependencies": true,
"typescript.preferences.autoImportFileExcludePatterns": [
"vue/dist/vue.d.ts"
]
}