User: 新手,下一步该从哪里开发
GitHub Copilot: 正在优化工具选择...你好!欢迎来到 Vue 的世界。从你的项目结构来看,你使用的是现代的 Vue 3 + Vite 构建的项目,并且已经包含了路由 (vue-router)。
你现在正在 src/components/Home.vue 文件中,这是一个非常好的起点!作为新手,建议你按照以下步骤循序渐进地开发:
第一步:跑起你的项目并实时预览
在写代码之前,确保你能实时看到修改的效果。打开 VS Code 的终端 (Terminal),在你的 my-vue-app 目录下运行:
npm install # 如果你还没有安装依赖的话
npm run dev # 启动本地开发环境
然后在浏览器中打开它提示的本地地址(通常是 http://localhost:5173)。
第二步:熟悉 Vue 组件的三大块
在你当前打开的 src/components/Home.vue 中,尝试编写最基础的结构。Vue 的文件主要分为三部分,你可以直接在文件里测试以下代码:
<template>
<!-- 1. 这里写 HTML 结构 -->
<div class="home-container">
<h1>我的第一个 Vue 页面</h1>
<p>当前点击次数: {{ count }}</p>
<button @click="addCount">点我加1</button>
</div>
</template>
<script setup>
// 2. 这里写 JavaScript 逻辑代码
import { ref } from 'vue'
// 定义一个响应式变量(数据变了,页面会自动更新)
const count = ref(0)
// 定义一个普通的方法
const addCount = () => {
count.value++
}
</script>
<style scoped>
/* 3. 这里写 CSS 样式。scoped 表示这里的样式只在当前组件生效,不会污染全局 */
.home-container {
text-align: center;
padding: 20px;
}
button {
padding: 8px 16px;
background-color: #42b983;
color: white;
border: none;
border-radius: 4px;
}
</style>
练习: 保存文件后,去浏览器看看是不是页面已经更新了?点一下按钮试试。
第三步:理解应用是如何串联的
熟悉了单页面开发后,你可以去看看项目是怎么把页面连起来的:
- 入口逻辑:去看看 src/main.js,这是整个项目启动的地方。
-
全局骨架:去看看 src/App.vue。这里通常放全站通用的东西(比如顶部导航栏),里面会有一个
<router-view />标签,它的作用就是根据当前的网址,替换显示对应的页面(比如首页就显示Home.vue)。 -
页面路由:去看看 src/router/index.js。这里配置了网址和组件的对应关系,比如告诉程序:“当访问
/时,展示Home组件”。
第四步:给自己布置一个小任务
当你把上面的内容看懂后,可以尝试独立完成这个任务:
- 在
src/components/目录下新建一个About.vue(关于我们页面),随便写点内容。 - 去 src/router/index.js 中把这个新页面配置上去(比如路径叫
/about)。 - 去 src/App.vue 中加两个可以点击跳转的菜单链接:
<router-link to="/">首页</router-link> | <router-link to="/about">关于</router-link>
你可以先从修改 Home.vue 里的文字和样式开始,随便玩!遇到不知道怎么写的功能(比如:怎么渲染一个列表、起名报错了怎么办),随时发代码问我。
User: 下一步
GitHub Copilot: 读取 [](file:///Users/jaunce/Desktop/H5/my-vue-app/src/router/index.js)
读取 [](file:///Users/jaunce/Desktop/H5/my-vue-app/src/App.vue)
太棒了!我们现在正式开始“第二步”:创建你的第二个页面,并让它们互相跳转(这叫做“路由导航”)。
通常,一个稍微复杂点的应用都不会只有一个页面。我们将带你一起添加一个“关于我 (About)”的页面。咱们分成 3 个小步骤来做:
1. 新建一个 About.vue 页面
在你当前 src/components/Home.vue 所在的同一级文件夹(src/components/)下,新建一个名为 About.vue 的文件,并贴入以下基本骨架:
<template>
<div class="about-container">
<h2>这是“关于”页面</h2>
<p>这个页面用来介绍你自己,或者写点项目的说明。</p>
</div>
</template>
<script setup>
// 你可以在这里加点逻辑相关的代码
</script>
<style scoped>
.about-container {
padding: 20px;
text-align: center;
color: #666;
}
</style>
2. 告诉系统这个页面的网址
Vue 不知道你有这个新页面,只有在路由(Router)里注册了,才能分配网址给它。
打开并修改你的路由配置文件:src/router/index.js:
将原来的:
import Home from '../components/Home.vue'
修改为:
import Home from '../components/Home.vue'
// 【新增】引入你刚刚创建的页面
import About from '../components/About.vue'
然后在 routes 数组里追加一个关于页面的路由项。修改后的完整代码会像这样:
import { createRouter, createWebHistory } from 'vue-router'
import Home from '../components/Home.vue'
import About from '../components/About.vue' // 引入新组件
const routes = [
{
path: '/',
redirect: '/home'
},
{
path: '/home',
name: 'Home',
component: Home
},
// 【新增】关于页面的网址
{
path: '/about',
name: 'About',
component: About
}
]
const router = createRouter({
history: createWebHistory(),
routes
})
export default router
现在你在浏览器输入 http://localhost:5173/about 应该就能直接看到刚才新建的关于页了!(端口号视你的运行情况而定)
3. 加个“导航菜单栏”
我们总不能指望用户手动敲网址来切页面,我们要加两个能点击的链接!
因为导航栏是所有页面都会展示的通用部分,所以最适合写在最外层的外壳文件里 —— 打开 src/App.vue,将其修改为:
<template>
<div class="nav-bar">
<!-- router-link 相当于传统的超链接 <a> 标签,但它不会让网页闪烁刷新,体验就像刷 App 一样顺滑!-->
<router-link to="/home">首页</router-link>
<span class="divider">|</span>
<router-link to="/about">关于</router-link>
</div>
<hr>
<!-- 这里是你真实页面组件展示的地方 -->
<router-view></router-view>
</template>
<style scoped>
.nav-bar {
text-align: center;
padding: 10px;
background-color: #f5f5f5;
}
.nav-bar a {
margin: 0 10px;
text-decoration: none;
color: #333;
font-weight: bold;
}
.nav-bar a.router-link-active {
color: #42b983; /* 当前激活状态会变绿 */
}
.divider {
color: #ccc;
}
</style>
做完这 3 步,你就完整地实现了一个多页面系统的核心功能。快在你的项目里试着敲一下!如果不成功,随时告诉我报错信息~
User: 新建页面的快捷键是什么
GitHub Copilot: 在 VS Code (macOS 环境) 中,新建页面(文件)主要有这几种最常用的快捷方式:
1. 快捷键新建 (适合键盘流)
- 按下
Cmd + N(Command + N),这会马上打开一个新的空白文件。 - 接着按
Cmd + S(Command + S) 保存。 - 在弹出的保存窗口中,将文件名改为
About.vue,并把保存位置选择在src/components/文件夹下。
2. 侧边栏按钮新建 (最推荐新手,不易弄错目录)
- 在左侧的代码文件树(资源管理器)中,鼠标点击选中
src/components文件夹。 - 点击文件夹旁边出现的 “新建文件” (New File) 图标(图标看起来像一张带
+号的纸)。 - 直接输入文件名
About.vue然后敲回车即可。
💡 效率小提示 (快速生成页面骨架):
每次新建 Vue 文件都要手敲 <template>、<script>、<style> 非常繁琐。
新建好 About.vue 文件后,你可以:
- 在空白文件里输入
vue或者vbase(取决于你安装的 Vue 代码提示插件)。 - 按
Enter或Tab键,工具会自动帮你把 Vue 文件的三大块骨架瞬间生成好!
现在你可以试试用上面的方法新建你的 About.vue 页面了!
User: 在空白文件里输入 vue 或者 vbase(取决于你安装的 Vue 代码提示插件)。
按 Enter 或 Tab 键,工具会自动帮你把 Vue 文件的三大块骨架瞬间生成好,没有生成三大骨架
GitHub Copilot: 出现这种情况,是因为 VS Code 默认没有内置 Vue 的快捷代码片段,需要安装专门的扩展插件才行。
别让这个小问题卡住你的进度!我们分两步来解决:
第一部分:先手动把骨架复制进去(别卡进度)
既然你已经建好了 About.vue,请先直接把下面这段最基础的 Vue 3 骨架复制并粘贴到这个空白文件里保存:
<template>
<div class="about-page">
<h2>这是关于页面</h2>
</div>
</template>
<script setup>
import { ref } from 'vue'
</script>
<style scoped>
.about-page {
padding: 20px;
}
</style>
第二部分:一劳永逸,安装代码提示插件
为了以后都能“瞬间生成”,你需要去 VS Code 的插件市场装个小插件:
- 点击 VS Code 最左侧边栏的 “扩展 (Extensions)” 图标(外观是四个小方块,快捷键
Cmd + Shift + X)。 - 在顶部的搜索框里输入:
Vue VSCode Snippets - 找到作者是 Sarah Drasner 的那个老牌经典插件,或者找
Vue 3 Snippets(作者 hollowtree),点击 “安装 (Install)”。 - 安装完成后,下次你再新建一个
.vue空白文件:- 输入
vbase-css或者vbase-3-setup(具体取决于你装的插件),然后敲回车,骨架瞬间就出来了!
- 输入
如果你装的是另一款必备的官方核心插件 Vue - Official(以前叫 Volar,写 Vue 必装),输入 vue 或 vbase 通常也会有一些基础提示。
你可以先复制上面的代码把 About.vue 跑起来,再继续我们之前的第三步:去 src/router/index.js 里配置它的网址。一切顺利吗?
User: 下一步
GitHub Copilot: 读取 [](file:///Users/jaunce/Desktop/H5/my-vue-app/src/router/index.js#1-1),行 1 到 20
读取 [](file:///Users/jaunce/Desktop/H5/my-vue-app/src/router/index.js)
读取 [](file:///Users/jaunce/Desktop/H5/my-vue-app/src/App.vue#1-1),行 1 到 30
读取 [](file:///Users/jaunce/Desktop/H5/my-vue-app/src/App.vue)
我刚刚检查了一下你的代码,非常棒!
你已经成功把 About.vue 创建好了,并且在 src/router/index.js 中配置了路由,也在 src/App.vue 中加入了导航栏。
如果你在浏览器看到页面可以点击“首页”和“关于”并来回切换(并且不变绿),说明你已经成功掌握了 Vue.js 项目最核心的“单页面路由跳转(SPA)” 概念了!🎉
既然地基已经打好,那么真正的开发往往包含下面两个极其常用的需求。作为 第三步(进阶),你可以选择一个方向继续:
选项 A:模拟真实业务 —— 页面加载时向后端发起请求
真实的项目一进页面都需要从服务器拉取数据。在 Vue 里,你可以用“生命周期”来实现。
我们去修改一下刚才新建的 About.vue,给它加上请求天气或用户数据的模拟逻辑。把你那边的 src/components/About.vue (或者 Home )内容添加进这段代码:
<template>
<div class="about-page">
<h2>关于页面</h2>
<!-- 如果没加载好显示 Loading,加载好了显示内容 -->
<div v-if="loading">正在拼命加载中...</div>
<div v-else>
<p>服务器返回的信息如下:</p>
<ul>
<!-- 使用 v-for 循环渲染列表数据 -->
<li v-for="(item, index) in dataList" :key="index">
{{ item.name }} - {{ item.job }}
</li>
</ul>
</div>
</div>
</template>
<script setup>
import { ref, onMounted } from 'vue'
const loading = ref(true) // 是否正在加载
const dataList = ref([]) // 存储数据的列表
// onMounted 意思是:“当页面刚刚被塞进网页里(渲染完成)的那一瞬间,执行里面的代码”
onMounted(() => {
// 我们用 setTimeout 模拟向后端请求数据花费了 1.5 秒
setTimeout(() => {
// 假装这是从后端接口返回的数据
dataList.value = [
{ name: '张三', job: '前端开发' },
{ name: '李四', job: '后端开发' },
{ name: '王五', job: '全栈工程师' }
]
loading.value = false // 数据拿到了,关闭加载状态
}, 1500)
})
</script>
<style scoped>
.about-page {
padding: 20px;
}
ul {
background: #f9f9f9;
padding: 20px;
border-radius: 8px;
}
</style>
看点:这里你掌握了 onMounted (页面加载完毕时触发) 、v-if (条件显示)、v-for (循环)。
选项 B:引入 UI 组件库(因为你的文件夹叫 H5)
既然你的父文件夹叫 H5,说明你这可能要做一个手机端的网页。
自己手写按钮、弹窗太累了,真实开发都会接入成熟的 UI 库,比如移动端最流行的就是 Vant 或者 NutUI。
你想先尝试 选项A(学习获取数据和循环) 还是 选项B(教你引入高阶 UI 库来搭界面的积木)?或者你想做点别的什么功能,直接告诉我!
User: loading.value = false 之后,为什么立即就关掉了,原理是什么
GitHub Copilot: 这正是 Vue 最核心、最强大的魅力所在,也就是大家常说的 “响应式系统(Reactivity System)”。
在传统的开发方式(比如原生 JavaScript 或 jQuery)中,如果数据变了,你需要手动去写代码操作网页元素,比如 document.getElementById('loading').style.display = 'none'。
但在 Vue 中,你不需要手动操作网页元素,它的原理可以分为三个步骤来理解:
1. ref 的魔法包装(数据劫持)
当你写下:
const loading = ref(true)
Vue 并不是简单地存了一个 true。ref 就像是一个带监控的快递盒子。你把 true 放进盒子里,以后你每次读写盒子里面的东西(通过 .value),Vue 都能立刻察觉到:“哦!有人修改了 loading 的值!”。
2. 建立牵绊(收集依赖)
在你的 HTML 模板中,你写了这样的代码:
<div v-if="loading">正在拼命加载中...</div>
<div v-else>...</div>
当 Vue 第一次把页面画出来时,它发现这里用到了 loading 变量。Vue 的内部笔记会默默记下一笔:“这个 v-if 的显示隐藏,和 loading 这个盒子绑定了。只要盒子里的值变了,我就要回来重新处理这块 HTML。”
3. 自动触发更新(响应变化)
1.5 秒后,定时器触发了:
loading.value = false
这时候发生了什么?
- 你把盒子里的值改为了
false。 - 盒子的“监控警报”立刻响起,通知 Vue 的系统。
- Vue 翻开之前的笔记,发现
v-if依赖于loading。 - Vue 瞬间在底层做计算:现在
loading是false了,所以v-if="loading"不成立,把它从页面上删掉;然后把下面的v-else加到页面上。 - 你肉眼看到的结果,就是“正在加载”瞬间消失,真实数据瞬间出现。
总结也就是一句口诀:
数据驱动视图(数据变了,页面自动变)。
你只需要关心“我要把数据改成什么样”,剩下的“怎么改变网页上的标签”,全都由 Vue 自动在底层瞬间帮你完成。这就是框架帮你省下的最大程度解放双手的地方!
User: 下一步
GitHub Copilot: 既然你已经理解了最核心的“数据驱动视图”,并且成功渲染了一个列表。下一步,也是真实开发中最常见的场景:表单输入与数据过滤。
我们将学习两个超级强大的 Vue 魔法:
-
v-model(双向绑定):只要你在输入框打字,Vue 里的变量就会自动更新;反过来变量改变,输入框内容也会变。 -
computed(计算属性):当你的数据变化时(比如输入了搜索词),它可以自动帮你重新计算(比如过滤出符合条件的列表项),非常智能!
第四步:给我们的列表加一个“搜索过滤”功能
我们要修改你目前的 src/components/About.vue 文件。我将直接帮你把搜索功能写进去:
正在将 [](file:///Users/jaunce/Desktop/H5/my-vue-app/src/components/About.vue) 中的 19 行替换为 43 行
我已经直接帮你把代码修改进 src/components/About.vue 文件啦!
在弄懂了数据“驱动视图”(ref 修改数据,页面自动隐藏 loading)之后,下一步我们需要掌握另外两个 Vue 最核心、最常用的语法法宝:双向绑定(v-model) 和 计算属性(computed)。
我刚才帮你在这个组件里加了一个“搜索过滤列表”的功能。快去浏览器看看效果:等 1.5 秒数据刷出来后,在输入框里打字试试!
现在,跟着我重点理解这两个新概念是怎么配合干活的:
新知识 1: v-model(双向绑定)
在表单和输入框中,你会用到它:
<input type="text" v-model="keyword" />
它叫做“双向绑定”,意思是:
-
视图 -> 数据:只要你在输入框敲键盘打字,底层的
keyword.value会立刻同步更新!(不需要你手动去监听oninput事件)。 -
数据 -> 视图:如果你的代码里修改了
keyword.value = '测试',输入框里的字会立刻变成“测试”。
数据和屏幕输入,两边永远像照镜子一样保持一致。
新知识 2: computed(计算属性)
有了上面的 keyword 和原有的 dataList,要怎么实现搜索列表呢?这就需要用 computed:
const filteredList = computed(() => {
// 返回过滤后的列表
return dataList.value.filter(...)
})
computed 就像一个极其聪明的雇员:
- 只要它依赖的数据(这里是
keyword或dataList)发生了哪怕一丁点改变,它都会瞬间帮你算出一个新的结果。 - 原先你的
<ul>循环的是写死的dataList,现在将它替换成v-for="(item, index) in filteredList",所以当你打字时,keyword改变 ->filteredList从新计算 -> 页面列表瞬间刷新出过滤的结果。一气呵成!
目前为止,响应式数据 ref、双向绑定 v-model、计算属性 computed、条件渲染 v-if / 数据循环 v-for。这些就是 Vue 80% 的工作量都在打交道的东西。
你看这些概念好消化吗?如果全懂了,我们下一步去学怎么把一个比较大型的页面拆成几块,也就是关于组件之间的传参(Props & Emits)!
已进行更改。
User: 懂了,下一步
GitHub Copilot: 已创建 [](file:///Users/jaunce/Desktop/H5/my-vue-app/src/components/UserCard.vue)
正在将 [](file:///Users/jaunce/Desktop/H5/my-vue-app/src/components/About.vue) 中的 18 行替换为 38 行
太棒了,你刚才已经完全啃下了一块硬骨头(响应式原理)!
第四步(终极挑战):组件拆分与数据通信 (Props & Emits)
当你开发一个真实应用时,所有的代码全塞在一个页面(比如 About.vue)会导致文件变成几千行,难以维护。
“组件化”思想就是让你把能重复使用的区域(比如导航栏、卡片、列表项、弹窗)拆分成独立的小组件。
想象一下:About.vue 是一个“父组件”(大老板),而我们要拆出一个漂亮的用户卡片作为“子组件”(打工人)。老板要把数据派发给员工去渲染,员工处理了点击事件后,又要汇报给老板。
这也是最核心的面试题之一。我刚刚直接帮你新建了一个子组件,并修改了父组件。
原理拆解
请去浏览器看看现在 About 页面的变化(现在的列表变成了一张张独立的卡片,点击还能弹窗!)。让我们看看其中的奥秘:
1. 父传子:Props (大老板把任务交给打工人)
打开我们刚刚新建的子组件 src/components/UserCard.vue,看 script 里:
// 我定义了我这个组件需要两个参数才能干活:userName 和 userJob
const props = defineProps({
userName: String,
userJob: String
})
这就像打工人说:“老板,把员工姓名和职位告诉我,我就能把名片画出来。”
这时候,看看你在 src/components/About.vue (父组件)里是怎么调用的:
<UserCard :userName="item.name" :userJob="item.job" />
这就是老板通过在标签上写属性绑定(因为有冒号 : 所以代表传入的是变量而不是带引号写死的字符串),把名字和职位塞进了子组件体内。
2. 子传父:Emits (打工人有事向老板汇报)
在这个子组件里,如果用户点击了“点赞”按钮,它不能擅自修改父组件的顶级数据。它只能打一个小报告:
// 我声明了我可以向外发一种叫 'userLiked' 的信号
const emit = defineEmits(['userLiked'])
const handleLike = () => {
// 发射信号,附带信息:谁被点赞了
emit('userLiked', props.userName)
}
这时候,在父组件 src/components/About.vue 里:
<UserCard @userLiked="onChildLiked" />
这里的 @ 符号代表监听。意思是:“只要你在内部触发了 userLiked 这个信号,我这个父组件就执行我的 onChildLiked 大方法,然后弹个窗。”
阶段总结
如果你理解了:
-
基础骨架 (
template,script setup,style) -
路由跳转 (
vue-router,<router-view>) -
响应式与生命周期 (
ref,computed,v-model,onMounted) -
组件化通信 (拆分组件,
Props,Emits)
恭喜你!你已经把 Vue 3 这个游戏的“新手村主线剧情”全部通关了!现在的你完全有能力照猫画虎地堆砌业务页面了。
你可以花几分钟消化一下卡片的拆分。消化完可以向我提问,或者我们进入下一阶段:引入成熟的 UI 库快速产出工业级页面,或者配置网络请求工具 axios。你想选型!**
已进行更改。