From f2b0e74cd23d86d966e1ae8f99a8aeadb658740e Mon Sep 17 00:00:00 2001 From: bunny <1319900154@qq.com> Date: Sat, 21 Jun 2025 22:46:40 +0800 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20Vue2=20=E7=BB=84=E4=BB=B6=E9=80=9A?= =?UTF-8?q?=E4=BF=A1=E4=B8=8E=E4=BA=8B=E4=BB=B6=E5=A4=84=E7=90=86=E6=B7=B1?= =?UTF-8?q?=E5=BA=A6=E6=8C=87=E5=8D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- vue2-tutorials/single-file/demo2/src/App.vue | 8 +- .../demo9/Vue2 组件通信与事件处理深度指南.md | 186 ++++++++++++++++++ .../views/demo9/components/SutdentInfo.vue | 31 +++ .../demo2/src/views/demo9/index.vue | 47 +++++ 4 files changed, 269 insertions(+), 3 deletions(-) create mode 100644 vue2-tutorials/single-file/demo2/src/views/demo9/Vue2 组件通信与事件处理深度指南.md create mode 100644 vue2-tutorials/single-file/demo2/src/views/demo9/components/SutdentInfo.vue create mode 100644 vue2-tutorials/single-file/demo2/src/views/demo9/index.vue diff --git a/vue2-tutorials/single-file/demo2/src/App.vue b/vue2-tutorials/single-file/demo2/src/App.vue index 30ccd70..b34bd10 100644 --- a/vue2-tutorials/single-file/demo2/src/App.vue +++ b/vue2-tutorials/single-file/demo2/src/App.vue @@ -8,7 +8,8 @@ - + + @@ -19,11 +20,12 @@ // import Demo4 from "@/views/demo4/index.vue"; // import Demo5 from "@/views/demo5/index.vue"; // import Todo from "@/views/todo/index.vue"; -import Demo8 from "@/views/demo8/index.vue"; +// import Demo8 from "@/views/demo8/index.vue"; +import Demo9 from "@/views/demo9/index.vue"; export default { name: "App", // components: { Demo1, Demo2, Demo3 }, - components: { Demo8 }, + components: { Demo9 }, }; diff --git a/vue2-tutorials/single-file/demo2/src/views/demo9/Vue2 组件通信与事件处理深度指南.md b/vue2-tutorials/single-file/demo2/src/views/demo9/Vue2 组件通信与事件处理深度指南.md new file mode 100644 index 0000000..193859b --- /dev/null +++ b/vue2-tutorials/single-file/demo2/src/views/demo9/Vue2 组件通信与事件处理深度指南.md @@ -0,0 +1,186 @@ +# Vue2 组件通信与事件处理深度指南 + +## 一、组件通信核心方式 + +### 1. 父子组件通信模式 + +#### Props 向下传递 +```javascript +// 父组件 + + +// 子组件 +props: { + title: String +} +``` + +#### Events 向上传递 +```javascript +// 子组件 +this.$emit('update', newValue) + +// 父组件 + +``` + +### 2. 引用直接访问 +```javascript +// 父组件 + + +methods: { + callChildMethod() { + this.$refs.childRef.childMethod() + } +} +``` + +## 二、事件系统高级用法 + +### 1. 原生事件绑定 +```html + + +``` + +### 2. 手动事件管理 +```javascript +// 绑定事件(推荐在mounted钩子中) +mounted() { + this.$refs.studenInfo.$on("getStudentName", this.getStudentName) +} + +// 解绑事件(必须在beforeDestroy中清理) +beforeDestroy() { + this.$refs.studenInfo.$off("getStudentName") +} +``` + +### 3. 事件参数传递 +```javascript +// 子组件触发时可带多个参数 +this.$emit('event-name', arg1, arg2, ...) + +// 父组件接收所有参数 +handler(arg1, arg2, ...rest) { + // 处理参数 +} +``` + +## 三、最佳实践建议 + +### 1. 事件命名规范 +- 使用 kebab-case 命名(如 `student-updated`) +- 避免与原生事件重名(添加业务前缀) +- 语义化命名(如 `form-submitted`) + +### 2. 安全通信模式 +```javascript +// 添加事件存在性检查 +if (this._events['custom-event']) { + this.$emit('custom-event', data) +} + +// 使用try-catch包裹可能出错的事件处理 +try { + this.$emit('critical-action', payload) +} catch (error) { + console.error('事件处理失败:', error) +} +``` + +### 3. 性能优化方案 +```javascript +// 防抖处理高频事件 +methods: { + handleInput: _.debounce(function() { + this.$emit('input-changed', this.value) + }, 300) +} +``` + +## 四、高级通信场景 + +### 1. 跨级组件通信 +```javascript +// 祖先组件 +provide() { + return { + appData: this.sharedData + } +} + +// 后代组件 +inject: ['appData'] +``` + +### 2. 动态事件处理器 +```javascript +// 根据状态切换处理函数 + + +data() { + return { + currentHandler: 'default', + handlerMap: { + default: this.handleDefault, + special: this.handleSpecial + } + } +} +``` + +### 3. 事件总线模式 +```javascript +// event-bus.js +import Vue from 'vue' +export default new Vue() + +// 组件A +EventBus.$emit('data-updated', payload) + +// 组件B +EventBus.$on('data-updated', handler) +``` + +## 五、常见问题解决方案 + +1. **事件未触发排查**: + - 检查组件引用是否正确(`ref` 命名) + - 确认事件名称完全匹配(大小写敏感) + - 验证事件绑定时机(确保在 mounted 之后) + +2. **内存泄漏预防**: + ```javascript + beforeDestroy() { + // 清除所有自定义事件监听 + this.$off() + // 清除事件总线监听 + EventBus.$off('data-updated', this.handler) + } + ``` + +3. **异步事件处理**: + ```javascript + // 返回Promise的事件处理 + async handleEvent() { + try { + await this.$nextTick() + const result = await this.$emitAsync('async-event') + // 处理结果 + } catch (error) { + // 错误处理 + } + } + ``` + +## 六、与Vue3的对比 + +| 特性 | Vue2 | Vue3 | +| -------- | -------------- | -------------------- | +| 事件定义 | 隐式声明 | `emits` 选项显式声明 | +| 原生事件 | 需要 `.native` | 自动识别 | +| 移除API | - | 移除 `$on`, `$off` | +| 性能 | 基于观察者 | 基于Proxy的响应式 | + diff --git a/vue2-tutorials/single-file/demo2/src/views/demo9/components/SutdentInfo.vue b/vue2-tutorials/single-file/demo2/src/views/demo9/components/SutdentInfo.vue new file mode 100644 index 0000000..f230dab --- /dev/null +++ b/vue2-tutorials/single-file/demo2/src/views/demo9/components/SutdentInfo.vue @@ -0,0 +1,31 @@ + + + + 学生姓名:{{ studenName }} + + + + + + 向父组件传递学生姓名 + + + + + + + diff --git a/vue2-tutorials/single-file/demo2/src/views/demo9/index.vue b/vue2-tutorials/single-file/demo2/src/views/demo9/index.vue new file mode 100644 index 0000000..7b72300 --- /dev/null +++ b/vue2-tutorials/single-file/demo2/src/views/demo9/index.vue @@ -0,0 +1,47 @@ + + + + 学生姓名: + {{ studenName }} + + + + + + + +