组件通信 $parent、$children、$root、$refs、$attrs、$listeners、$bus、Vuex

this.$parent
可以访问到父组件 上所有的 data(){ 里的数据信息和生命周期方法,methods里的方法

// 子传父
this.$parent.datas = "val"
for(let i = 0; i < this.$children.length; i++) {
        console.log(this.$children[i].msg)//输出子组件的msg数据;
      }

$root

获取当前组件树的根 Vue 实例。如果当前实例没有父实例,此实例将会是其自己。通过 $root ,我们可以实现组件之间的跨级通信

$refs

我们通常会将 refs 绑定在子组件上,从而获取子组件实例

$attrs

a t t r s : 用 来 接 收 父 作 用 域 中 不 作 为 p r o p 被 识 别 的 a t t r i b u t e 属 性 , 并 且 可 以 通 过 v − b i n d = " attrs: 用来接收父作用域中不作为 prop 被识别的 attribute 属性,并且可以通过v-bind=" attrspropattributevbind="attrs"传入内部组件——在创建高级别的组件时非常有用

$listeners

l i s t e n e r s : 包 含 了 父 作 用 域 中 的 v − o n 事 件 监 听 器 。 它 可 以 通 过 v − o n = " listeners:包含了父作用域中的 v-on 事件监听器。它可以通过 v-on=" listenersvonvon="listeners" 传入内部组件——在创建更高层次的组件时非常有用,这里在传递时的使用方法和 $attrs 十分类似。

// A组件
<template>
  <div class="compa">
    <h3>this is A component</h3>
    <input type="text" v-model="message" />
    <p>收到来自{{ comp }}的消息:{{ messageFromComp }}</p>
    <CompB :messageFromA="message" @keyup="receive" />  <!--监听子孙组件的keyup事件,将message传递给子孙组件-->
  </div>
</template>
<script>
import CompB from './compB'
export default {
  name: 'CompA',
  data() {
    return {
      message: '',
      messageFromComp: '',
      comp: '',
    }
  },
  components: {
    CompB,
  },
  methods: {
    receive(e) { // 监听子孙组件keyup事件的回调,并将keyup所在input输入框的值赋值给messageFromComp
      this.comp = e.target.name
      this.messageFromComp = e.target.value
    },
  },
}
</script>
// 2级组件B
<template>
  <div class="compb">
    <h4>this is B component</h4>
    <input name="compB" type="text" v-model="message" v-on="$listeners" />  <!--A组件keyup的监听回调绑在该input上-->
    <p>收到来自A组件的消息:{{ $attrs.messageFromA }}</p>
    <CompC v-bind="$attrs" v-on="$listeners" /> <!--A组件keyup的监听回调继续传递给C组件,将A组件传递的attrs继续传递给C组件-->
  </div>
</template>
<script>
import CompC from './compC'
export default {
  name: 'CompB',
  components: {
    CompC,
  },
  data() {
    return {
      message: '',
    }
  },
}
</script>
// 3级组件C
<template>
  <div class="compc">
    <h5>this is C component</h5>
    <input name="compC" type="text" v-model="message" v-on="$listeners" /> <!--A组件keyup的监听回调绑在该input上-->
    <p>收到来自A组件的消息:{{ $attrs.messageFromA }}</p>
  </div>
</template>
<script>
export default {
  name: 'Compc',
  data() {
    return {
      message: '',
    }
  },
}
</script>

$bus

// main.js
Vue.prototype.$bus = new Vue()

```// 1级组件A
<template>
  <div class="containerA">
    <h2>this is CompA</h2>
    <input type="text" v-model="message" @keyup="sendMessage" />
    <p v-show="messageFromBus && sender !== $options.name">
      收到{{ sender }}的消息:{{ messageFromBus }}
    </p>
    <CompB />
  </div>
</template>
<script>
import CompB from './compB'
export default {
  name: 'CompA',
  components: {
    CompB,
  },
  data() {
    return {
      message: '',
      messageFromBus: '',
      sender: '',
    }
  },
  mounted() {
    this.$bus.$on('sendMessage', (obj) => {  // 通过eventBus监听sendMessage事件
      const { sender, message } = obj
      this.sender = sender
      this.messageFromBus = message
    })
  },
  methods: {
    sendMessage() {
      this.$bus.$emit('sendMessage', { // 通过eventBus触发sendMessage事件
        sender: this.$options.name,
        message: this.message,
      })
    },
  },
}
</script>
// 2级组件B
<template>
  <div class="containerB">
    <h3>this is CompB</h3>
    <input type="text" v-model="message" @keyup="sendMessage" />
    <p v-show="messageFromBus && sender !== $options.name">
      收到{{ sender }}的消息:{{ messageFromBus }}
    </p>
    <CompC />
    <CompD />
  </div>
</template>
<script>
import CompC from './compC'
import CompD from './compD'
export default {
  name: 'CompB',
  components: {
    CompC,
    CompD,
  },
  data() {
    return {
      message: '',
      messageFromBus: '',
      sender: '',
    }
  },
  mounted() {
    this.$bus.$on('sendMessage', (obj) => { // 通过eventBus监听sendMessage事件
      const { sender, message } = obj
      this.sender = sender
      this.messageFromBus = message
    })
  },
  methods: {
    sendMessage() {
      this.$bus.$emit('sendMessage', { // 通过eventBus触发sendMessage事件
        sender: this.$options.name,
        message: this.message,
      })
    },
  },
}
</script>
// 3级组件C
<template>
  <div class="containerC">
    <p>this is CompC</p>
    <input type="text" v-model="message" @keyup="sendMessage" />
    <p v-show="messageFromBus && sender !== $options.name">
      收到{{ sender }}的消息:{{ messageFromBus }}
    </p>
  </div>
</template>
<script>
export default {
  name: 'CompC',
  data() {
    return {
      message: '',
      messageFromBus: '',
      sender: '',
    }
  },
  mounted() {
    this.$bus.$on('sendMessage', (obj) => { // 通过eventBus监听sendMessage事件
      const { sender, message } = obj
      this.sender = sender
      this.messageFromBus = message
    })
  },
  methods: {
    sendMessage() {
      this.$bus.$emit('sendMessage', { // 通过eventBus触发sendMessage事件
        sender: this.$options.name,
        message: this.message,
      })
    },
  },
}
</script>
// 3级组件D
<template>
  <div class="containerD">
    <p>this is CompD</p>
    <input type="text" v-model="message" @keyup="sendMessage" />
    <p v-show="messageFromBus && sender !== $options.name">
      收到{{ sender }}的消息:{{ messageFromBus }}
    </p>
  </div>
</template>
<script>
export default {
  name: 'CompD',
  data() {
    return {
      message: '',
      messageFromBus: '',
      sender: '',
    }
  },
  mounted() {
    this.$bus.$on('sendMessage', (obj) => { // 通过eventBus监听sendMessage事件
      const { sender, message } = obj
      this.sender = sender
      this.messageFromBus = message
    })
  },
  methods: {
    sendMessage() {
      this.$bus.$emit('sendMessage', { // 通过eventBus触发sendMessage事件
        sender: this.$options.name,
        message: this.message,
      })
    },
  },
}
</script>

Vuex

全局通信:代码的内容和eventBus也类似,不过要比eventBus使用方便很多。每个组件通过watch监听input输入框的变化,把input的值通过vuex的commit触发mutations,从而改变stroe的值。然后每个组件都通过computed动态获取store中的数据,从而实现全局通信。

// store.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
  state: {
    message: {
      sender: '',
      content: '',
    },
  },
  mutations: {
    sendMessage(state, obj) {
      state.message = {
        sender: obj.sender,
        content: obj.content,
      }
    },
  },
})
// 组件A
<template>
  <div class="containerA">
    <h2>this is CompA</h2>
    <input type="text" v-model="message" />
    <p v-show="messageFromStore && sender !== $options.name">
      收到{{ sender }}的消息:{{ messageFromStore }}
    </p>
    <CompB />
  </div>
</template>
<script>
import CompB from './compB'
export default {
  name: 'CompA',
  components: {
    CompB,
  },
  data() {
    return {
      message: '',
    }
  },
  computed: {
    messageFromStore() {
      return this.$store.state.message.content
    },
    sender() {
      return this.$store.state.message.sender
    },
  },
  watch: {
    message(newValue) {
      this.$store.commit('sendMessage', {
        sender: this.$options.name,
        content: newValue,
      })
    },
  },
}
</script>
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值