Part1:父子组件

父组件给子组件传值不需要使用其他库,可以直接使用props传值,talk is cheap,show me the code!

Parent.vue

<template>
  <div class="hello">
    <h1 @click="changeMsg">click send message to child by props</h1>    //点击事件触发修改msg值,即可修改子组件的值
    <h2>props demo</h2>
    <children @receiveMsg="receive" :childMsg="msg"></children>    //使用:childMsg="msg"将子组件的变量与父组件的msg绑定起来,@receiveMsg作为子组件给父组件传值emit时的关键字
  </div>
</template>

<script type="es6">
import Children from '@/components/Children'    //引入子组件
export default {
  name: 'Parent',
  data () {
    return {
      msg: 'hello boy'
    }
  },
  components: {children: Children},    //注册子组件
  methods: {
    changeMsg () {
      this.msg = 'hello girl'
    },
    receive (data) {    //通过触发@receiveMsg事件而调用的函数
      console.log(data)
    }
  }
}
</script>

使用import引入子组件后,只需要将子组件props内的变量与父组件之间绑定起来,通过修改父组件data里面的值,即可达到对子组件的控制

Children.vue

<template>
  <div class="hello" style="border:1px solid #666">
    <h1>children component</h1>
    <h1>there is children component,receive message :{{childMsg}}</h1>    //此处使用props变量
    <h2 @click="send">click here send msg to parent</h2>
  </div>
</template>
<script>
export default {
  name: 'children',
  props: ['childMsg'],    //这里定义好变量
  data () {
    return {
      msg: 'child'
    }
  },
  methods: {
    send () {
      this.$emit('receiveMsg', 'from child')    //给父组件发送事件
    }
  }
}
</script>

子组件的props里面定义好childMsg即可接收父组件的改变,使用this.$emit即可向父组件传递事件触发,并传参

part2:非父子组件

非父子组件事件触发我只知道2种方式,但原理都是一样的,借助另一个对象转发事件。其中,事件中心插件vue-bus是我使用过的一种方式,效果也还可以,具体可参考 vue-bus文档 。

在这里,为了减少对其他库的依赖,直接new 一个Vue出来作为事件中心,效果和vue-bus几乎是一模一样的,但有无缺陷目前本人还无法得知。废话不多说,直接上代码。

main.js

import Vue from 'vue'
import App from './App'
import router from './router'

Vue.config.productionTip = false
Vue.prototype.bus = new Vue()    //此处全局注册一个Vue作为事件中心
/* eslint-disable no-new */
new Vue({
  el: '#app',
  router,
  components: { App },
  template: '<App/>'
})

Brother1.vue

<template>
  <div class="hello" style="border:1px solid #666">
    <h1>Brother1 component</h1>
    <h2 @click="send">click send onb2</h2>
  </div>
</template>
<script>
export default {
  name: 'Brother1',
  data () {
    return {
      msg: 'Brother1'
    }
  },
  methods: {
    send () {
      this.bus.$emit('onb2', 'from brother1') // 触发Brother2.vue监听的onb2事件
    }
  },
  created () {
    this.bus.$on('onb1', (param) => { // 创建时,进行事件onb1监听
      console.log('receive onb1', param)
    })
  },
  beforeDestroy () {
    this.bus.$off('onb1') // 销毁时,事件onb1监听取消
    console.log('onb1 listener was closed')
  }
}
</script>

Brother2.vue

<template>
  <div class="hello" style="border:1px solid #666">
    <h1>Brother2 component</h1>
    <h2 @click="send">click send onb1</h2>
  </div>
</template>
<script>
export default {
  name: 'Brother2',
  data () {
    return {
      msg: 'Brother2'
    }
  },
  methods: {
    send () {
      this.bus.$emit('onb1', 'from brother2') // 触发Brother1.vue监听的onb1事件
    }
  },
  created () {
    this.bus.$on('onb2', (param) => { // 创建时,进行事件onb1监听
      console.log('receive onb2', param)
    })
  },
  beforeDestroy () {
    this.bus.$off('onb2') // 销毁时,事件onb2监听取消
    console.log('onb2 listener was closed')
  }
}
</script>

需要注意的是,最好在页面实例销毁之前将事件监听取消掉,不然当你离开这个页面之后,事件监听是依然存在的,这样可能会造成一些不可预估的错误,除非你需要继续监听这个事件。

使用new Vue()这个方法不管是代码还是效果,几乎都和使用vue-bus一模一样。如果不想使用过多的插件库,这未免不是一个好方法(在我不知道副作用的情况下)。


that's all,对于以上的言论,如有不正确的地方,希望各位多多包涵并加以指正


Logo

前往低代码交流专区

更多推荐