前端开发的世界瞬息万变,每隔一段时间就会冒出新的框架和工具。但是经典永不过时,基于对经典的理解,才能更好的去上手其他框架,比如基于 Vue 的 Nuxt.js 等让我们一起来探索 Vue 3 和 Vite 这对黄金搭档,手把手搭建一个现代前端项目
# 一、为什么选择 Vue 3?
Vue 是一个广受欢迎的渐进式 JavaScript 框架,简单、灵活、功能强大。Vue 3 相较于 Vue 2 迎来了全面升级,以下是它的一些亮点:
- **Composition API:** 如果说 Vue 2 是温暖的家,Vue 3 的 Composition API 就是那间焕然一新的工作室。它带来了更好的逻辑复用和代码组织方式,特别适合大型项目。
- ** 性能优化:**Vue 3 的响应式系统基于 Proxy 实现,性能更快,占用内存更小。
- ** 更好的 TypeScript 支持:**TypeScript 和 Vue 3 是绝配,帮助你写出更稳定、更易维护的代码。
这里对 Vite 不做过多讲解,这篇主要简介怎么快速启动 Vue3+Vite 的项目,感兴趣的朋友可以去我的主页中看一下关于其详细的文章
# 二、Vite 是什么?为什么选它?
在传统的前端开发中,我们常用 Webpack 构建工具,但它的启动速度和构建性能往往会拖慢开发进程。Vite 则是个 “小火箭”:
- ** 极速冷启动:** 使用原生 ES 模块,秒级启动开发服务器,告别漫长的 “npm run dev”。
- ** 热模块替换(HMR):** 修改代码时,页面自动刷新,效果立竿见影,开发体验丝滑流畅。
- ** 简单易用:** 配置文件直观清晰,开箱即用,开发者友好。
# 三、👩💻 实战:用 Vue 3 + Vite 快速搭建项目
# 1. 安装项目
用以下命令创建你的 Vue 项目,我们详细讲解一下每个配置项:
## 1.创建命令
npm create vue@latest
## 2.具体配置
## 配置项目名称
√ Project name: vue3_test
## 是否添加TypeScript支持
√ Add TypeScript? Yes
## 是否添加JSX支持
√ Add JSX Support? No
## 是否添加路由环境
√ Add Vue Router for Single Page Application development? No
## 是否添加pinia环境
√ Add Pinia for state management? No
## 是否添加单元测试
√ Add Vitest for Unit Testing? No
## 是否添加端到端测试方案
√ Add an End-to-End Testing Solution? » No
## 是否添加ESLint语法检查
√ Add ESLint for code quality? Yes
## 是否添加Prettiert代码格式化
√ Add Prettier for code formatting? No
启动后访问 http://localhost:5173/ ,迎接你的就是 Vue 3 的默认界面了,是不是超快?
# 2. 了解 Vite 配置文件
在项目中找到 vite.config.ts 。这是 Vite 的大脑,控制你的开发环境和构建流程。大致结构如下:
import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';
export default defineConfig({
plugins: [vue()],
});
如果需要自定义环境变量,在根目录创建 .env 文件即可,例如: VITE_API_URL=https://api.example.com
# 四、项目启动之后的文件介绍
在使用 Vue 3 和 Vite 创建项目后,你会发现项目的核心文件包括 index.html 、 main.ts 和 App.vue 。对于这些核心文件的理解很为重要,所以我写好了详细的注释,帮助朋友们更好地理解它们的作用和结构。
# 1. index.html
这是项目的入口文件,也是传统意义上的 HTML 模板。Vite 使用 index.html 作为开发和构建的起点。
<!DOCTYPE html>
<html lang="en">
<head>
<!-- 网页的字符编码,确保页面正确显示多语言文本 -->
<meta charset="UTF-8" />
<!-- 设置视口,确保页面在移动设备上的良好展示效果 -->
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<!-- 页面标题,会显示在浏览器标签页 -->
<title>Vite + Vue</title>
</head>
<body>
<!-- #app 是 Vue 应用挂载的根元素 -->
<div id="app"></div>
<!-- 加载 Vite 提供的 JavaScript 入口文件 -->
<!-- Vite 会自动替换 `type="module"` 的引用为优化后的构建版本 -->
<script type="module" src="/src/main.ts"></script>
</body>
</html>
【关键点】
#app是 Vue 应用的挂载点,Vue 会通过main.ts将应用绑定到这个div元素。script引入了/src/main.ts,这个文件是 Vue 应用的启动入口。
# 2. main.ts
因为刚才创建项目的时候选择了 TypeScript,所以是 mian.ts 文件。这是 Vue 应用的主入口文件,用于创建应用实例并挂载到 DOM 上。
// 引入 createApp 方法,用于创建 Vue 应用实例
import { createApp } from 'vue';
// 引入根组件
import App from './App.vue';
// 引入样式文件(如果有全局样式,可以在这里引入)
import './global.css';
// 创建 Vue 应用实例,并将其挂载到 #app 元素上
createApp(App).mount('#app');
【关键点】
- **
createApp(App):** 创建了一个 Vue 应用实例,App是应用的根组件。- **
.mount('#app'):** 指定 Vue 应用实例挂载的位置(与index.html中的#app对应)。- ** 样式文件:** 通过
import './global.css'引入全局样式,你也可以使用预处理器文件如 SCSS 或 Less。
# 3. App.vue
这是应用的根组件,是所有 Vue 组件的起点。它包含 template 、 script 和 style 三部分。
<template>
<!-- 根模板,默认提供一个简单的内容 -->
<div id="app">
<h1>Vite + Vue</h1>
<p>Welcome to your Vue 3 + Vite project!</p>
</div>
</template>
<script setup>
// 这里是 `<script setup>` 语法,它是 Vue 3 的新特性,用于编写更简洁的组件逻辑
// 不需要 `export default`,也不用显式定义 `setup` 函数
</script>
/* 局部样式,作用于本组件 */
<style scoped>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>
【关键点】
template部分
- 定义组件的 HTML 结构和内容。
#app是根元素,组件的其他部分会插入到这里。
script setup部分
- 使用 Vue 3 的
<script setup>语法,直接编写组件逻辑。- 如果需要使用响应式数据,可以引入 Vue 的
ref或reactive方法。
style部分
默认情况下,CSS 样式只作用于本组件(通过生成作用域 CSS 实现)。
如果想局部生效,可以添加
style标签的
scoped属性:
<style scoped>
【小结】
index.html是静态模板,#app是 Vue 的挂载点,<script>引入项目主入口。main.ts用于创建和启动 Vue 应用实例,并将其绑定到#app。App.vue是根组件,作为整个应用的起点,可以在里面实现更多复杂的逻辑和布局。
# 五、开发初体验:父子组件通信
下面我们来实现一个基础的父子组件通信示例,分别通过 props 和 emit 进行数据传递。
# 1. 父组件 App.vue
<template>
<div>
<!-- 向子组件传递数据 message -->
<Home :message="parentMessage" @reply="handleReply" />
</div>
</template>
<script setup>
// 父组件的数据
const parentMessage = "Hello from Parent!";
// 父组件的方法,用于接收子组件的事件
const handleReply = (childMessage) => {
console.log("Received from child:", childMessage);
};
</script>
<style scoped>
/* 父组件的样式,仅影响本组件 */
div {
font-family: Arial, sans-serif;
margin: 20px;
}
</style>
【注释说明】
<Home :message="parentMessage" />
- 使用
props将数据从父组件传递给子组件。- 这里的
message是子组件接收的prop名,parentMessage是父组件的变量。@reply="handleReply"
- 通过事件监听
reply,父组件会调用handleReply方法,处理子组件传来的数据。- 数据和方法
parentMessage是父组件的变量,用于传递给子组件。handleReply是父组件的方法,用于接收子组件通过事件传递的数据。
# 2. 子组件 Home.vue
<template>
<div>
<!-- 显示父组件传递过来的数据 -->
<p>Parent says: {{ message }}</p>
<!-- 点击按钮触发事件,向父组件发送数据 -->
<button @click="sendReply">Reply to Parent</button>
</div>
</template>
<script setup>
// 子组件接收来自父组件的 props
defineProps({
message: String, // 定义 message 是一个字符串类型的 prop
});
// 子组件向父组件发送事件
const sendReply = () => {
// 使用 $emit 将数据发送给父组件
emit("reply", "Hello from Child!");
};
// 声明 emit 方法,告诉 Vue 子组件可能会触发哪些事件
defineEmits(["reply"]);
</script>
<style scoped>
/* 子组件样式,仅作用于本组件 */
div {
border: 1px solid #ccc;
padding: 10px;
margin: 10px;
text-align: center;
}
button {
background-color: #42b983;
color: white;
border: none;
padding: 5px 10px;
cursor: pointer;
}
button:hover {
background-color: #369c7d;
}
</style>
【注释说明】
defineProps
- 定义子组件需要从父组件接收的
props,这里的message类型是String。- 父组件传递的
message会被自动注入到子组件。defineEmits
- 定义子组件可以触发的事件,方便与父组件通信。
reply是事件名称,emit("reply", "Hello from Child!")会触发这个事件并传递数据。sendReply方法
- 子组件通过点击按钮调用
sendReply方法,触发reply事件,将数据发送给父组件。
# 3. 运行效果
- 父组件显示子组件传来的数据
- 父组件的控制台会输出:
"Received from child: Hello from Child!"。
- 父组件的控制台会输出:
- 页面内容
- 父组件传递的信息会显示在子组件中:
Parent says: Hello from Parent!。 - 点击按钮,子组件通过事件将数据传递给父组件。
- 父组件传递的信息会显示在子组件中:
# 4. 小结
-
props:用于父组件向子组件传递数据。 -
emit:用于子组件向父组件发送事件和数据。
这种通信方式是 Vue 中最基础、最常用的父子组件交互模式。如果有更复杂的场景,比如跨层级组件通信,可以考虑使用 Vuex 或 Pinia 等其他方式,我打算后续专门写一篇文章来讲解多种组件通信,因为实在是太多种通信方式了,一会儿父子传一会儿爷孙传一会儿兄弟传,刚开始学习的时候都要给我绕晕了,不知道有没有朋友跟我一样的困扰,所以我打算整理总结一篇出来。
