Vue-admin工作整理(八): BUS | | 组件通信

一、父子组件之间通信

  思路:定义一个个人组件,个人组件通常需要在前缀统一命名一下,如:AInput,该组件的作用是将编辑框中的内容获取并通过事件提交出去,然后在目标组件(store)中通过双向交互模式(v-model)来接收。具体实现为:

  1、路由列表增加一个入口:

 {
    path: '/store',
    name: 'store',
    component: () => import('@/views/store.vue')
  },

  2、定义自定义组件:AInput(components->AInput):

<template>
  <input @input="handleInput" :value="value"/>
</template>
<script>
export default {
  name: 'AInput',
  props: {
    value: {
      type: [String, Number],
      default: ''
    }
  },
  methods: {
    handleInput (event) {
      const value = event.target.value
      this.$emit('input', value)
    }
  }
}
</script>

AInput设计逻辑:通过事件对象event的属性值来获取用户输入的内容,然后通过定义的input事件像外传出去,this.$emit的作用是触发自定义的input函数,该函数值就是用户输入的内容。

  3、store组件中用来呈现用户输入的内容

<template>
  <div>
    <a-input v-model="inputValue"/>
    <p>{{ inputValue }}</p>
  </div>
</template>
<script>
import AInput from '_c/AInput.vue'
export default {
  name: 'store',
  data () {
    return {
      inputValue: ''
    }
  },
  components: {
    AInput
  }
}
</script>

store实现思路:首先将事件组件(AInput)引进来,然后在通过components将其注册进来,再通过a-input来呈现AInput组件,只是是需要通过用 v-model来绑定用户在上一个组件中输入的值,这个值被命名为inputValue,并要在data里初始化一下,然后通过{{ inputValue }} 展示录入内容。

总结:v-model这个指令是一个双向绑定,它是一个语法堂,AInput的处理(<input @input="handleInput" :value="value"/>)实际就是通过input事件来处理用户的操作,通过:value绑定呈现用户输出的内容,而v-model实际的处理应该是<a-input: value="inputValue" @input="handleInput"/>,就是通过input事件的handleInput方法来获取用户输入的数据,然后通过 :value来获取呈现输入的内容。store的:value就是AInput里的props: {value: 属性值

备注:父子组件向子组件传值,一定是通过属性,而子组件想要修改父组件传来的值,必须通过事件的方式,把需要修改的值以参数的形式,放在自定义函数(this.$emit)里,提交给父组件,然后父组件通过绑定一个事件,来知道子组件要改一个值,改值的操作要在子组件里修改

二、兄弟组件之间通信:

思路:父组件引入AInput的兄弟组件:AShow组件,该组件中定义一个属性:content,用来获取兄弟组件AInput输入的内容,然后父组件 store中在components将AShow注册进来,再通过a-show来呈现,该步骤中是通过 绑定content来获取inputValue的返回值。

  1、兄弟组件:AShow:

<template>
  <div>
    <p>AShow: {{ content }}</p>
  </div>
</template>
<script>
export default {
  props: {
    content: {
      type: [String, Number],
      default: ''
    }
  }
}
</script>

  2、父组件:store.vue:

<template>
  <div>
    <a-input v-model="inputValue"/>
    <p>{{ inputValue }}</p>
    <a-show :content = "inputValue"/>
  </div>
</template>
<script>
import AInput from '_c/AInput.vue'
import AShow from '_c/AShow.vue'
export default {
  name: 'store',
  data () {
    return {
      inputValue: ''
    }
  },
  components: {
    AInput,
    AShow
  }
}
</script>

备注:两个兄弟组件是通过父组件来进行交互的

三、跨文件的两个组件之间的通信(BUS):

  1、bus->index.js:

import Vue from 'vue'  // 引入vue
const Bus = new Vue()  // 创建Bus实例
export default Bus  // 导出Bus

  2、在main.js中将Bus引入进来

import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import Bus from './bus'. // 引入

Vue.config.productionTip = false
Vue.prototype.$bus = Bus  // 将Bus注册到根实例里:使用Vue.prototype属性在原型对象上添加$bus,并将Bus赋值给$bus,这样在
new Vue实例里就注入了Bus
 new Vue({ router, store, render: h => h(App) }).$mount('#app')

  3、在email.vue组件中创建一个mounted(生命周期钩子),目的是创建一个空的Vue实例来作为交互的中介,如何使用呢:通过email.vue组件中创建一个事件,然后再通过自定义函数的方式触发"on-click"事件,并需要给on-click赋值,例如“hello”,后提交给$bus,然后在另一个组件tel.vue里再接手这个事件,如何接手呢:通过在该组件里增加一个监听事件,来获取message的值

<template>
  <div class="email">
    Email: 8130512@QQ.com
    <p>
      <button @click="handleChick">点我</button>
    </p>
  </div>
</template>
<script>
export default {
  methods: {
    handleChick () {
      this.$bus.$emit('on-click', '做自己擅长的!!!') //this.$bus.$emit触发当前实例上的事件,把on-click事件绑定在$bus上
} },
mounted () {
   console.log(
this.$bus)
  }
}

</script>
<style lang="less" scoped>
  .email{ border: 1px solid green; }
</style>

  4、tel.vue:

<template>
  <div class="tel">
    Tel: 19999999999
    <p>
      {{ message }}
    </p>
  </div>
</template>
<script>
export default {
  data () {
    return {
      message: ''
    }
  },
  mounted () {
    this.$bus.$on('on-click', (mes) => {  // 给当前事件绑定一个事件监听,读取$bus里的on-click事件
      this.message = mes
    })
  }
}
</script>
<style lang="less" scoped>
.tel{
  border: 1px solid red;
}
</style>

 

原文地址:https://www.cnblogs.com/cristin/p/9598538.html