您好,欢迎访问一九零五行业门户网

vue组件通信的方法介绍(附代码)

本篇文章给大家带来的内容是关于vue组件通信的方法介绍(附代码),有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。
vue 的组件化应该是其最核心的思想了,无论是一个大的页面还是一个小的按钮,都可以被称之为组件。基于 vue 的开发,就是在写一个个组件,无论是基础组件还是业务组件,最后都是要拼装在一起。按照组件的层级关系,可以把组件之间的关系归纳为:父子关系、隔代关系、兄弟关系,无关联关系。
$ref 、$parent 、$children
基于当前上下文的,可以通过 $ref 、$parent 、$children 访问组件实例,可以直接调用组件的方法或访问数据。其中 $parent 可以访问当前组件的父组件,$children 可以访问当前组件的所有子组件。虽然 $parent 和 $children 都可以获取组件实例,但是它们无法在跨级或兄弟间通信,这是它们的缺点。
provide 、inject
provide / inject 是 vue 在 2.2.0 版本后新增的 api。
这对选项需要一起使用,以允许一个祖先组件向其所有子孙后代注入一个依赖,不论组件层次有多深,并在起上下游关系成立的时间里始终生效。
也就是在父组件中提供一个值,并且在需要使用的子孙组件中注入改值,即:
// parent.vueexport default {    provide() {        return {            name: 'stone'        }    }}// child.vueexport 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 进行数据管理。
本篇文章到这里就已经全部结束了,更多其他精彩内容可以关注的javascript教程视频栏目!
以上就是vue组件通信的方法介绍(附代码)的详细内容。
其它类似信息

推荐信息