vue组件通讯的办法介绍(附代码)
vue 的组件化应当是其最中心的思想了,不管是一个大的页面还是一个小的按钮,都可以被称之为组件。基于 Vue 的开发,就是在写一个个组件,不管是根基组件还是业务组件,最后都是要拼装在一起。依照组件的层级关系,可以把组件之间的关系归纳为:父子关系、隔代关系、兄弟关系,无关联关系。
$ref 、$parent 、$children
基于当前上下文的,可以通过 $ref 、$parent 、$children 拜访组件实例,可以直接调取组件的办法或拜访数据。其中 $parent 可以拜访当前组件的父组件,$children 可以拜访当前组件的所有子组件。虽然 $parent 和 $children 都可以猎取组件实例,但是它们没法在跨级或兄弟间通讯,这是它们的缺陷。
provide 、inject
provide / inject 是 Vue 在 2.2.0 版本后新增的 API。
这对选项需要一起使用,以同意一个祖先组件向其所有子孙后代注入一个依靠,不管组件层次有多深,并在起上下流关系成立的时间里始终生效。
也就是在父组件中供给一个值,并且在需要使用的子孙组件中注入改值,即:
// Parent.vue export default { provide() { return { name: 'Stone' } } } // Child.vue export default { inject: ['name'], mounted() { console.log(this.name) } }
不仅仅是 Child.vue ,只如果 Parent.vue 的子组件,不管隔多少代,都可以通过这个的方式注入。 这种多级组件透传的方式可以包管单向数据流的清楚性,例如像会员信息这样的全局信息,就可以借助这两个 API 来完成,而没有引入第三方库 vuex。
替换 Vuex
vuex 是把数据集中治理,然后哪里需要就在哪里猎取,依照这个思绪,我们可以在根组件 App.vue 中注入全局信息,并且在页面的任何地方使用。
// App.vue <template> <div> <router-view></router-view> </div> </template> export default { provide() { return { userInfo: this.user } }, data() { return { user: {} } }, methods: { getUserInfo () { $.ajax('/user/info', (data) => { this.user = data }) } } }
把整个 App.vue 的实例 this
对外供给, 这样其他页面就可以通过 this.userInfo
来猎取会员信息。
<template> <div> {{ userInfo }} </div> </template> <script> export default { inject: ['userInfo'] } </script>
$dispatch 、 $broadcast
这两个 API 是 Vue 1.0 版本的,$dispatch 用于向上级派发事件,$broadcast 用于向下级播送事件的,它们在 2.0 版本中已经被废弃了。
由于基于组件树构造的事件流方式有时让人难以懂得,并且在组件构造扩展的历程中会变得越来越脆弱。
不外我们可以自行实现 dispatch 和 broadcast 办法,用于组件的跨层级通讯。它们实现的关键在于怎样准确寻到所要通讯的组件,也就是通过匹配组件的 name 选项向下或向上查寻组件。
这两个办法都需要传递 3 个参数,第一个参数是要通讯组件的 name 选项值,第二个是自定义事件名称,第三个是要给通讯组件传递的值。在 dispatch 里,通过 while 轮回不竭向上查寻父组件,直到查寻到 componentName 与某个父级组件的 name 选项匹配时完毕,此时改父组件就是要通讯的组件。 broadcast 办法与 dispatch 相似,是通过 forEach 轮回向下查寻子组件。 最后封装一个 mixins 来便于复用。
// emitter.js function broadcast(componentName, eventName, params) { this.$children.forEach(child => { const name = child.$options.name; if (name === componentName) { child.$emit.apply(child, [eventName].concat(params)); } else { broadcast.apply(child, [componentName, eventName].concat([params])); } }); } export default { methods: { dispatch(componentName, eventName, params) { let parent = this.$parent || this.$root; let name = parent.$options.name; while (parent && (!name || name !== componentName)) { parent = parent.$parent; if (parent) { name = parent.$options.name; } } if (parent) { parent.$emit.apply(parent, [eventName].concat(params)); } }, broadcast(componentName, eventName, params) { broadcast.call(this, componentName, eventName, params); } } };
通过 mixins 混入组件,实现组件间的通讯。
<!-- Parent.vue --> <template> <button @click="handleClick"> 触发事件 <Child></Child> </button> </template> <script> import Emitter from "../assets/js/emitter.js"; import Child from "./Child.vue"; export default { name: "Parent", mixins: [Emitter], created() { this.$on("on-message", message => { console.log(message); }); }, components: { Child }, methods: { handleClick() { this.broadcast("Child", "on-message", "Hello, I am Parent Component"); } } }; </script>
<!-- Child.vue --> <template> <div></div> </template> <script> import Emitter from "../assets/js/emitter.js"; export default { name: "Child", mixins: [Emitter], mounted() { this.$on("on-message", message => { console.log(message); this.dispatch("Parent", "on-message", "Copy that, I am Child Component"); }); } }; </script>
比拟 Vue 1.0 版本内置的两个 API,自行实现的办法有以下不一样:
- 需要额别传入组件的 name 作为第一个参数;
- 匹配到组件就会休止轮回,不会冒泡;
- 传递的值只能是一个参数,假如需要传递多个参数,只能通过对象或数组的情势;
其他办法
在 vue 中组件的通讯还有其他的手法,例如:
props
、$emit
<!-- Parent.vue --> <template> <Child :info="info" @update="onUpdateName"></Child> </template> <script> import Child from "./Child.vue"; export default { data() { return { info: { name: "stone" } }; }, components: { Child }, methods: { onUpdateName(name) { this.info.name = name; } } }; </script>
<!-- Child.vue --> <template> <div> <div>{{info.name}}</div> <button @click="handleUpdate">update</button> </div> </template> <script> export default { props: { info: { type: Object, default: {} } }, methods: { handleUpdate() { this.$emit("update", "new-name"); } } }; </script>
父组件将本人的办法传递给子组件,子组件调取办法传数据给父组件使用event bus事件总线$attrs 、$listenersVue 2.4 新增的 API。
$attrs 包括了父作用域中不作为 prop 被识别 (且猎取) 的特性绑定 (class 和 style 除外)。
$listeners 包括了父作用域中的 (不含 .native 润饰器的) v-on 事件监听器。Vuex 集中式状态治理
写在最后
不一样的通讯办法适用于不一样的场景,既可以通过 Vue 内置的 API 来通讯,也可以通过自定义事件的方式实现通讯办法,当利用足够复杂状况下,就可以使用 Vuex 停止数据治理。
本篇文章到这里就已经全部完毕了,更多其他出色内容可以关注PHP中文网的JavaScript教程视频栏目!
以上就是vue组件通讯的办法介绍(附代码)的具体内容,更多请关注百分百源码网其它相关文章!