{{ course.title }}
++ {{ course.finished ? "已完成" : "学习中" }} +
+ +diff --git a/08-vue3/01-create-app-and-ref/README.md b/08-vue3/01-create-app-and-ref/README.md new file mode 100644 index 0000000..1fd02ec --- /dev/null +++ b/08-vue3/01-create-app-and-ref/README.md @@ -0,0 +1,23 @@ +# 练习 1:createApp、setup 和 ref + +## 目标 + +学会用 Vue3 的 `createApp` 和 `setup()` 启动页面,并用 `ref` 创建最基础的响应式数据。 + +## 你要练什么 + +- `createApp` +- `setup()` +- `ref` +- 模板插值 + +## 任务 + +- 显示页面标题和学习人数 +- 点击按钮后让人数加 1 +- 在控制台输出最新人数 + +## 文件 + +- [starter.html](/Users/lijiaqing/home/wwwroot/front-end-example/08-vue3/01-create-app-and-ref/starter.html) +- [starter.js](/Users/lijiaqing/home/wwwroot/front-end-example/08-vue3/01-create-app-and-ref/starter.js) diff --git a/08-vue3/01-create-app-and-ref/starter.html b/08-vue3/01-create-app-and-ref/starter.html new file mode 100644 index 0000000..fb563d0 --- /dev/null +++ b/08-vue3/01-create-app-and-ref/starter.html @@ -0,0 +1,23 @@ + + +
+ + +当前学习人数:{{ learnerCount }}
+ +总课时:{{ course.totalLessons }}
+已完成:{{ course.finishedLessons }}
+{{ progressText }}
+ +当前输入:{{ keyword }}
++ {{ course.finished ? "已完成" : "学习中" }} +
+ +数据加载中...
+{{ error }}
+{{ course.finished ? "已完成" : "学习中" }}
+ +当前阶段:{{ stage }}
+学习天数:{{ studyDays }}
+主题模式:{{ settings.theme }}
当前关键字:{{ keyword }}
+我是子组件
+ +异步组件加载中...
+ +这里应该通过 Teleport 渲染到 body。
+ +这里会展示异步组件内容。
+ `, + }, + }, + setup() { + const showModal = ref(false); + + return { + showModal, + }; + }, +}).mount("#app"); diff --git a/08-vue3/13-script-setup-macros/README.md b/08-vue3/13-script-setup-macros/README.md new file mode 100644 index 0000000..88fb9bc --- /dev/null +++ b/08-vue3/13-script-setup-macros/README.md @@ -0,0 +1,26 @@ +# 练习 13:script setup、defineProps、defineEmits、defineExpose + +## 目标 + +补上 Vue3 在工程化单文件组件里的核心宏语法。 + +## 你要练什么 + +- ` + + diff --git a/08-vue3/README.md b/08-vue3/README.md new file mode 100644 index 0000000..b1f0851 --- /dev/null +++ b/08-vue3/README.md @@ -0,0 +1,141 @@ +# Vue3(组合式 API + 响应式原理) + +你的学习文档里这一章的定位是 `Vue3(组合式API + 响应式原理)`。这一章我按这个方向来拆,不再重复 Vue2 的 Options API 主线,而是重点转到 Vue3 的组合式写法和响应式思维。 + +## 学完后你应该掌握 + +- Vue3 和 Vue2 的核心差异 +- `createApp` +- `setup()` +- `ref` +- `reactive` +- `toRef` +- `toRefs` +- `readonly` +- `computed` +- `watch` +- `watchEffect` +- `nextTick` +- 组合式 API 生命周期 +- 模板 `ref` +- `props` 和 `emit` +- 组件 `v-model` +- `slot` +- `provide` / `inject` +- `expose` +- composable 的基本抽离方式 +- `script setup` +- `defineProps` +- `defineEmits` +- `defineExpose` +- `Teleport` +- `Suspense` +- `Transition` +- 如何用 Vue3 写一个小型管理面板 + +## 这一章在解决什么 + +Vue2 更强调“选项式组织”。 + +Vue3 这一章要解决的是: + +- 逻辑如何按功能组织,而不是按选项分散 +- 响应式数据如何在 `setup()` 里组合 +- 一段可复用逻辑如何抽成 composable +- 组件之间如何在组合式 API 下继续通信 + +## 全部知识点清单 + +### 基础入口 + +- `createApp` +- `setup()` +- `return` + +### 响应式核心 + +- `ref` +- `reactive` +- `toRef` +- `toRefs` +- `readonly` +- `computed` +- `watch` +- `watchEffect` +- `nextTick` + +### 生命周期与 DOM + +- `onBeforeMount` +- `onMounted` +- `onBeforeUpdate` +- `onUpdated` +- `onBeforeUnmount` +- `onUnmounted` +- 模板 `ref` +- `expose` + +### 组件通信 + +- `props` +- `emit` +- 组件 `v-model` +- `slot` +- `provide` +- `inject` + +### 逻辑复用 + +- composable +- 异步状态管理 +- `loading` +- `error` + +### 工程化语法与内置组件 + +- `script setup` +- `defineProps` +- `defineEmits` +- `defineExpose` +- `Teleport` +- `Suspense` +- `Transition` + +## 学习顺序 + +1. `createApp`、`setup()` 和 `ref` +2. `reactive` 和 `computed` +3. `watch` 和 `watchEffect` +4. 生命周期和模板 `ref` +5. `props` 和 `emit` +6. `slot` 与 `provide` / `inject` +7. composable 与异步状态 +8. `toRefs`、`readonly` 等响应式辅助工具 +9. `nextTick` 和组件 `v-model` +10. before 系列生命周期与 `expose` +11. `Teleport`、`Suspense`、`Transition` +12. `script setup` 宏 +13. 综合小页面 + +## 练习目录 + +- [01-create-app-and-ref/README.md](/Users/lijiaqing/home/wwwroot/front-end-example/08-vue3/01-create-app-and-ref/README.md) +- [02-reactive-and-computed/README.md](/Users/lijiaqing/home/wwwroot/front-end-example/08-vue3/02-reactive-and-computed/README.md) +- [03-watch-and-watch-effect/README.md](/Users/lijiaqing/home/wwwroot/front-end-example/08-vue3/03-watch-and-watch-effect/README.md) +- [04-lifecycle-and-template-ref/README.md](/Users/lijiaqing/home/wwwroot/front-end-example/08-vue3/04-lifecycle-and-template-ref/README.md) +- [05-props-and-emits/README.md](/Users/lijiaqing/home/wwwroot/front-end-example/08-vue3/05-props-and-emits/README.md) +- [06-slots-and-provide-inject/README.md](/Users/lijiaqing/home/wwwroot/front-end-example/08-vue3/06-slots-and-provide-inject/README.md) +- [07-composable-and-async/README.md](/Users/lijiaqing/home/wwwroot/front-end-example/08-vue3/07-composable-and-async/README.md) +- [08-final-dashboard/README.md](/Users/lijiaqing/home/wwwroot/front-end-example/08-vue3/08-final-dashboard/README.md) +- [09-reactivity-helpers/README.md](/Users/lijiaqing/home/wwwroot/front-end-example/08-vue3/09-reactivity-helpers/README.md) +- [10-next-tick-and-component-v-model/README.md](/Users/lijiaqing/home/wwwroot/front-end-example/08-vue3/10-next-tick-and-component-v-model/README.md) +- [11-before-hooks-and-expose/README.md](/Users/lijiaqing/home/wwwroot/front-end-example/08-vue3/11-before-hooks-and-expose/README.md) +- [12-built-in-components/README.md](/Users/lijiaqing/home/wwwroot/front-end-example/08-vue3/12-built-in-components/README.md) +- [13-script-setup-macros/README.md](/Users/lijiaqing/home/wwwroot/front-end-example/08-vue3/13-script-setup-macros/README.md) + +## 说明 + +- 这一章只提供 `starter`,不提供 `answer` +- 为了降低门槛,练习使用浏览器 CDN 版本的 Vue3 +- `13-script-setup-macros` 是 SFC 语法练习,文件是 `.vue` starter,不是直接双击运行的 HTML +- 如果后面你要把这一章升级成 `Vite + Vue3`,我可以再继续补工程化版本 diff --git a/09-interview-plan/README.md b/09-interview-plan/README.md new file mode 100644 index 0000000..10a8927 --- /dev/null +++ b/09-interview-plan/README.md @@ -0,0 +1,217 @@ +# 前端面试官 Prompt + +你现在扮演一位有经验的前端面试官,负责基于这个学习仓库的内容,对候选人进行系统化面试训练。 + +## 你的任务 + +围绕下面 8 个知识单元出题、追问、点评,并帮助候选人把“会写”升级成“会讲”: + +- HTML +- CSS +- JavaScript Core +- DOM + 事件 + 异步 +- ES6+ +- TypeScript +- Vue2 +- Vue3 + +## 你的工作方式 + +### 1. 按阶段出题 + +请按下面 4 个阶段组织面试题: + +#### 第一阶段:结构与样式 + +- HTML +- CSS + +目标: + +- 检查候选人是否能把页面拆成结构 +- 检查候选人是否能解释常见布局方案 + +#### 第二阶段:JavaScript 主线 + +- JavaScript Core +- DOM + 事件 + 异步 +- ES6+ + +目标: + +- 检查候选人是否能说清基础语法、作用域、闭包、`this` +- 检查候选人是否能说清事件流、异步、模块化 + +#### 第三阶段:类型与 Vue2 + +- TypeScript +- Vue2 + +目标: + +- 检查候选人是否能解释类型系统的价值 +- 检查候选人是否能说清 Vue2 的数据驱动和组件通信 + +#### 第四阶段:Vue3 与综合表达 + +- Vue3 + +目标: + +- 检查候选人是否能说清组合式 API、响应式、composable 和工程化语法 + +### 2. 每次只出一个单元 + +每次面试时: + +1. 先让我选择一个单元 +2. 再连续提出 5 到 8 道问题 +3. 每题都允许我回答 +4. 你根据我的回答继续追问 + +### 3. 每道题都按这个顺序处理 + +对每道题,请按下面流程进行: + +1. 先提出问题 +2. 等我回答 +3. 判断回答是否完整 +4. 如果不完整,继续追问 +5. 最后给出点评 + +## 你的提问标准 + +每道题尽量围绕这 4 层来设计: + +1. 定义是什么 +2. 使用场景是什么 +3. 常见坑点是什么 +4. 能不能举一个小例子 + +## 题目池 + +### HTML + +- 什么是语义化标签?为什么不要只用 `div`? +- 一个完整 HTML 文档的基本骨架包含哪些部分? +- 块级元素和行内元素的区别是什么? +- `section`、`article`、`aside` 分别适合什么场景? +- `ul` / `ol` / `li` 的嵌套规则是什么? +- `form`、`label`、`input` 的正确关系是什么? +- `alt`、`href`、`src`、`name` 分别有什么作用? +- 为什么说 HTML 更像页面骨架而不是样式代码? + +### CSS + +- 盒模型由哪些部分组成? +- `margin` 和 `padding` 的区别是什么? +- `display: block / inline / inline-block / flex / grid` 的常见差异是什么? +- Flex 最常用的几个属性分别解决什么问题? +- Grid 适合什么场景?和 Flex 的区别是什么? +- `position: relative / absolute / fixed / sticky` 分别怎么理解? +- 什么是文档流?脱离文档流会带来什么影响? +- 如何做水平垂直居中? + +### JavaScript Core + +- `var`、`let`、`const` 的区别是什么? +- JavaScript 常见数据类型有哪些? +- `undefined` 和 `null` 的区别是什么? +- `if / else` 和 `switch` 各适合什么场景? +- `for` 和 `while` 的区别是什么? +- 什么是函数?参数和返回值怎么理解? +- 数组和对象分别适合存什么数据? +- 什么是作用域?什么是闭包? +- `this` 在普通函数、对象方法、箭头函数里的区别是什么? +- 值传递和引用传递怎么理解? + +### DOM + 事件 + 异步 + +- 如何选中页面元素? +- `textContent`、`innerHTML`、`classList`、`style` 有什么常见用途? +- 如何创建、插入、删除节点? +- `addEventListener` 的作用是什么? +- 事件冒泡是什么?事件委托为什么有用? +- `preventDefault()` 和 `stopPropagation()` 分别解决什么问题? +- `setTimeout` 为什么体现异步? +- Promise 和 `async/await` 在页面交互里怎么配合? + +### ES6+ + +- 模板字符串和字符串拼接相比有什么优势? +- 解构赋值的典型使用场景是什么? +- 展开运算符和剩余参数分别做什么? +- 箭头函数和普通函数的差异有哪些? +- 为什么箭头函数里的 `this` 容易被问到? +- `import / export` 的基本写法是什么? +- `fetch()` 和 `res.json()` 的关系是什么? +- Promise 和 `async/await` 的关系是什么? + +### TypeScript + +- TypeScript 和 JavaScript 的核心差异是什么? +- 为什么说 TypeScript 的价值主要发生在运行前? +- 基本类型、数组类型、函数类型怎么写? +- `interface` 适合解决什么问题? +- 泛型 `