当前位置: 首页 > news >正文

织梦网站如何做二级导航有网站代码怎么做网站

织梦网站如何做二级导航,有网站代码怎么做网站,广州建设专修学院,网站的导航栏设计文本事件总线(Event Bus)事件总线(Event Bus)是一种实现跨组件通信的简便方法。它特别适用于那些没有直接父子关系的兄弟组件或深层嵌套组件之间的通讯。消息总线实际上就是一个空的 Vue 实例,用于触发和监听事件。创建消息…

 

事件总线(Event Bus)

事件总线(Event Bus)是一种实现跨组件通信的简便方法。它特别适用于那些没有直接父子关系的兄弟组件或深层嵌套组件之间的通讯。消息总线实际上就是一个空的 Vue 实例,用于触发和监听事件。

创建消息总线

首先,你需要创建一个独立的 Vue 实例作为事件总线。通常的做法是在项目的某个地方创建这个实例,并导出它以便其他组件使用。

// eventBus.js
import Vue from 'vue';
export const EventBus = new Vue();

使用消息总线进行通讯

发送消息(Emitting Events)

要从一个组件发送消息,可以使用 $emit 方法来触发一个事件,并且可以传递数据给这个事件。

// 在需要发送消息的组件中
import { EventBus } from './eventBus.js';export default {methods: {sendMessage() {EventBus.$emit('message', '一些数据');}}
}
接收消息(Listening to Events)

要在另一个组件中接收这条消息,你可以使用 $on 方法来监听特定的事件。

// 在需要接收消息的组件中
import { EventBus } from './eventBus.js';export default {created() {EventBus.$on('message', (data) => {console.log(data); // 输出:一些数据});},beforeDestroy() {// 清理事件监听器以避免内存泄漏EventBus.$off('message');}
}

注意事项

  1. 清理事件监听器:当组件销毁时,应该记得移除所有的事件监听器,以防止内存泄漏。可以使用 EventBus.$off('eventName') 来取消注册特定事件的监听器。

  2. 命名冲突:由于所有组件共享同一个事件总线,因此需要小心处理事件名称,以免发生冲突。推荐使用模块化或者前缀的方式来区分不同功能的事件。

  3. 复杂场景下的替代方案:对于更复杂的场景,比如状态管理涉及到多个组件、深层次嵌套或是全局状态的管理,Vuex 是更为推荐的解决方案。Vuex 提供了一个集中式的存储来管理应用的所有组件状态,遵循单向数据流的原则。

  4. Vue 3 的变化:在 Vue 3 中,由于 Vue 的内部架构发生了改变,特别是关于事件系统的变化,导致了传统的事件总线模式不再适用。不过,在 Vue 3 中可以通过第三方库如 Mitt 或者自己创建一个简单的 EventEmitter 来达到类似的目的。

通过使用消息总线,可以在不引入额外依赖的情况下轻松实现非父子组件间的简单通信。然而,随着应用规模的增长,可能需要考虑更加健壮的状态管理解决方案,如 Vuex。

provide-inject

在 Vue 2.2.0 及以上版本中引入的 provideinject,为组件间通信提供了一种新的方式。这种方式特别适用于祖先和后代组件之间的通信,无需通过 $parent 或事件总线等手段进行显式的引用传递。

基本概念

  • provide: 允许一个祖先组件向其所有子孙组件(无论层级多深)提供数据或方法。在父组件中使用 provide 选项来指定哪些数据或方法可以被它的子组件(及其嵌套的子组件)所访问。这个选项应该是一个对象或返回对象的函数,对象中的每个属性将会成为后代组件可以通过 inject 访问的数据项。

  • inject: 允许一个后代组件接收来自祖先组件提供的数据或方法。在需要访问提供的数据或方法的组件中使用 inject 选项。它同样可以是一个字符串数组或者一个对象。如果是数组,则数组中的每一项代表从提供者那里注入的一个依赖的名字。如果是对象,则可以更详细地定义每个注入依赖的配置,比如默认值等。

这种方式非常适合用于插件开发、高阶组件(HOC)或者需要跨多层组件共享状态的场景。

使用示例

祖先组件
// 祖先组件定义
export default {provide() {return {userName: 'Alice',userAge: 30,getUserInfo() {return `${this.userName} is ${this.userAge} years old.`;}};},// 注意:这里的 this 指向当前实例,但在 inject 中使用 getUserInfo 方法时,this 不再指向祖先实例
};

为了确保 getUserInfo 方法中的 this 正确指向祖先组件实例,可以使用箭头函数或通过 provide 返回一个对象字面量,并利用 Vue 的响应式特性。

改进后的例子:

export default {data() {return {userName: 'Alice',userAge: 30};},provide() {return {userName: this.userName,userAge: this.userAge,getUserInfo: () => `${this.userName} is ${this.userAge} years old.`};}
};
后代组件
// 后代组件定义
export default {inject: ['userName', 'userAge', 'getUserInfo'],created() {console.log(`Injected userName: ${this.userName}`); // 输出: Injected userName: Aliceconsole.log(`Injected userAge: ${this.userAge}`);   // 输出: Injected userAge: 30console.log(this.getUserInfo());                     // 输出: Alice is 30 years old.}
};

特点与注意事项

  1. 非响应式默认行为:默认情况下,provide 提供的数据不是响应式的。如果希望提供的数据是响应式的,可以使用 Vue 实例的属性或结合 computed 属性来实现。

  2. 响应式解决方案

    • 使用 Vue 实例的属性:如上面的例子所示,直接从 data 函数返回的对象中获取属性。

    • 使用 computed:如果需要更复杂的逻辑处理,可以考虑使用计算属性。

  3. 避免滥用:虽然 provide/inject 提供了强大的功能,但它打破了组件间的封装性,可能导致代码难以维护。因此,它更适合用于构建可复用的组件库或插件,而不是日常业务逻辑中的首选方案。

  4. 生命周期考量provide 是在组件创建之前执行的,这意味着你不能在 provide 中依赖尚未初始化的数据或方法。

  5. Vue 3 改进:在 Vue 3 中,provideinject 得到了增强,支持了更多的特性和更好的类型推断,同时保持了与 Vue 2 类似的使用模式。

provide 实现响应式

provide 提供的对象本身不是自动响应式的,但如果你 provide 的是 Vue 实例上的一个响应式数据(如 data 中的属性),并且在 inject 后的组件中正确访问其属性,那么这些属性的

关键点解析

  1. provide 的值来源决定响应性

    • 如果你在 provide 中直接提供一个字面量对象,它不是响应式的

      // ❌ 非响应式 - 提供的是字面量对象
      provide() {return {userInfo: { name: 'Alice', age: 30 } // 这个对象本身不是响应式 Vue 实例}
      }

      在这种情况下,即使你修改了 userInfo 对象内部的属性(比如 this.injectedUserInfo.name = 'Bob'),不会触发视图更新,因为这个对象没有被 Vue 的响应式系统追踪。

    • 如果你 provide 的是组件 data 中的一个响应式对象,那么这个对象的属性变化是响应式的

      // ✅ 响应式 - 提供的是 data 中的响应式对象
      data() {return {userInfo: { name: 'Alice', age: 30 } // userInfo 是响应式对象}
      },
      provide() {return {userInfo: this.userInfo // 提供的是响应式对象的引用}
      }
  2. inject 后的访问方式

    • 当你 inject 一个来自 data 的响应式对象时,你获得的是对那个响应式对象的引用。
    • 在 inject 组件中直接修改这个对象的属性(如 this.userInfo.name = 'Bob'会触发响应式更新,因为你在修改的是原始的、被 Vue 追踪的响应式对象。
    • 但是,不能直接替换整个被注入的对象。例如 this.userInfo = { name: 'Bob', age: 25 } 这样会破坏响应式连接,新对象不会被追踪。
  3. 推荐做法(Vue 2.6+): 为了更清晰地处理响应式数据,Vue 2.6+ 引入了 Vue.observable()。你可以使用它来创建一个响应式对象并提供出去。

    import Vue from 'vue';const state = Vue.observable({userInfo: { name: 'Alice', age: 30 }
    });const mutations = {updateName(name) {state.userInfo.name = name;}
    };// 在父组件中
    provide() {return {state,      // 提供响应式状态mutations  // 提供修改状态的方法}
    }

    在子组件中:

    inject: ['state', 'mutations'],
    computed: {userName() {return this.state.userInfo.name; // 这是响应式的}
    },
    methods: {changeName() {this.mutations.updateName('Bob'); // 通过方法修改,确保响应式}
    }

总结

  • provide/inject 本身不创造响应式
  • 传递复杂对象时,只有当提供的对象本身是 Vue 的响应式对象(来自 data 或 Vue.observable())时,其属性的变更才是响应式的
  • 直接提供字面量对象会导致非响应式行为。
  • 推荐使用 Vue.observable() 结合 provide/inject 来管理跨层级的响应式状态,或者考虑使用 Vuex 进行更复杂的状态管理。

其他实现provide响应式方式


✅ 方法一:提供整个 this(推荐,简单有效)

这是最常见且有效的实现响应式 provide/inject 的方式。

祖先组件(响应式)
// Ancestor.vue
export default {name: 'Ancestor',data() {return {userName: 'Alice',userAge: 30}},provide() {// 提供整个 this,它是一个响应式 Vue 实例return {parent: this // 命名为 parent 或其他你喜欢的名字}},methods: {updateUserInfo() {this.userName = 'Bob'this.userAge = 28}},template: `<div><h2>祖先组件</h2><p>当前用户: {{ userName }}, 年龄: {{ userAge }}</p><button @click="updateUserInfo">更新用户信息</button><slot></slot> <!-- 插槽,用于放置后代组件 --></div>`
}
后代组件(接收并响应)
// Descendant.vue
export default {name: 'Descendant',inject: ['parent'], // 注入祖先的实例computed: {// 使用计算属性自动响应 parent 的变化userInfo() {return {name: this.parent.userName,age: this.parent.userAge}}},methods: {// 也可以直接调用祖先的方法callAncestorMethod() {console.log(this.parent.getUserInfo())}},template: `<div style="border: 1px solid red; margin: 10px; padding: 10px;"><h3>后代组件(响应式)</h3><p>注入的用户名: {{ userInfo.name }}</p><p>注入的年龄: {{ userInfo.age }}</p><button @click="callAncestorMethod">调用祖先方法</button></div>`
}

效果:当点击祖先组件的“更新用户信息”按钮时,userNameuserAge 变化,后代组件中的显示也会自动更新


✅ 方法二:提供一个 reactive 对象(更精细控制)

如果你不想暴露整个 this,可以创建一个专门用于共享的响应式对象。

// Ancestor.vue
import Vue from 'vue'export default {data() {return {userName: 'Alice',userAge: 30}},created() {// 创建一个响应式对象用于共享this.sharedState = Vue.observable({userName: this.userName,userAge: this.userAge})},provide() {return {sharedState: this.sharedState}},watch: {// 监听本地数据变化,同步到共享状态userName(newVal) {this.sharedState.userName = newVal},userAge(newVal) {this.sharedState.userAge = newVal}},methods: {updateUserInfo() {this.userName = 'Charlie'this.userAge = 35}},template: `<div><h2>祖先组件</h2><p>本地用户: {{ userName }}, 年龄: {{ userAge }}</p><p>共享状态: {{ sharedState.userName }}, {{ sharedState.userAge }}</p><button @click="updateUserInfo">更新</button><slot></slot></div>`
}
// Descendant.vue
export default {inject: ['sharedState'],template: `<div style="border: 1px solid blue; margin: 10px; padding: 10px;"><h3>后代组件</h3><p>共享用户名: {{ sharedState.userName }}</p><p>共享年龄: {{ sharedState.userAge }}</p></div>`
}

💡 Vue.observable() 是 Vue 2.6+ 引入的 API,用于创建一个响应式对象。


最佳实践:对于大多数场景,方法一(提供 this 是最简单有效的响应式 provide/inject 实现方式。

总结

provideinject 提供了一种简单而有效的方法来实现在多层嵌套组件间共享状态或功能,尤其是在构建可复用组件或插件时非常有用。然而,在实际项目中应谨慎使用,以维持良好的代码结构和可维护性。对于大多数常规的父子组件通信需求,推荐继续使用 props$emit 来保证组件间的清晰解耦。

http://www.dtcms.com/a/475562.html

相关文章:

  • 网络建设的网站十大进销存管理软件
  • 最新电大网站开发维护静态html转wordpress
  • 免费建网站软件家具制作网站
  • 企业网站内容运营方案案例关于网站建设的方案ppt
  • 设计专业网站公司自助网站免费建站平台
  • 四川省的住房和城乡建设厅网站首页基于营销导向的企业网站建设研究
  • (CVPR 2025 最佳论文)【源码复现】VGGT: Visual Geometry Grounded Transformer”
  • 网站策划书包括哪些内容全国响应式网站建设
  • 抵押网站建设方案wordpress 短代码插件
  • 做调查的网站知乎wordpress 上传到域名
  • 国外购买域名的网站wordpress模板内容修改
  • 病历邮寄怎么进入公众号南宁seo排名外包
  • wordpress个人建站教程亚马逊跨境电商平台官网
  • 什么服装网站做一件代发wordpress能接口
  • 广州建设水务局网站汽车推广软文
  • 网站开发产生费用分录怎么写网站建设论文标题
  • 5.2 天空盒和反射探针
  • 浙江省门户网站青岛中企动力做网站怎么样
  • 人力外包网站网站网页设计培训机构
  • 免费静态网站托管平台如何做网页赚钱
  • 银川网站建站免费模板网站推荐
  • 手机网站开发需要哪些人网络营销方案的制定思路
  • 变量、标识符
  • 网站备案 99国家高新技术企业查询系统
  • Kubernetes 网络插件 Flannel 与 Calico 三种工作模式详解
  • 网站建设策划书范文案例商城网站 备案
  • 营销型网站建设五大内容合肥seo网络营销推广
  • 任务网站(做任务学技能的)wordpress获取附件id
  • 菜谱网站 源码备份wordpress
  • 4.2 > Linux 文件/目录权限管理【核心命令】