20200506 Vue组件 组件通信

组件关系可分为:父子组件通信,兄弟组件通信,跨级组件通信

自定义事件---子组件给父组件传递数据

使用v-on 除了监听 DOM 事件之外,还可以用于组件之间的自定义事件。
子组件使用 $emit()触发事件,父组件使用 $on()监听子组件事件

第一步:自定义事件
第二步:在子组件中使用$emit 触发事件,第一个参数是要触发的事件名,后面的参数是要传递的数据
第三步:在自定义事件中用一个参数来接收

    <div id="app">
        你的银行卡余额是:{{total}}
        <son-component @change='handelTotal'></son-component>
        <!-- 自定义的change事件 -->
    </div>


    <script>
        Vue.component('son-component', {
            template: `<div>
                <button @click='addMoney'> +1000 </button>
                <button @click='minusMoney'> -1000 </button>
            </div>`,
            data: function () {
                return {
                    count: 2000
                }
            },
            methods: {
                addMoney() {
                    this.count = this.count + 1000
                    this.$emit('change', this.count)
                //触发change事件,并传递给它一个参数this.count
                },
                minusMoney() {
                    this.count = this.count - 1000
                    this.$emit('change', this.count)
                }
            }
        })

       let app = new Vue({
            el: '#app',
            data: {
                total: 2000
            },
            methods: {
                handelTotal(value) {
                    //此处的形参value 就是子组件传递过来的数据,即上面的 this.count
                    this.total = value
                }
            }
        })
    </script>
</body>

非父子关系组件之间的通信 --- 父链---子链

有时候两个非父子关系的组件也需要通信,在简单的场景下,可以使用一个空的 vue 实例作为中央事件总线(中介):

let bus = new Vue()
//bus 为自定义名称,非固定写法

//触发组件 a 中的事件:
bus.$emit('a-component',1)

//在组件 b 创建的钩子函数中监听事件
bus.$on('a-component',function(id){
   //......
 })

从组件a向组件b中传递数据,首先要在根组件中定义一个 bus 中介
在a组件中通过 this.$root.bus 拿到根组件中的 bus 中介,再通过this.$root.bus.$emit('lala',this.aaa)去触发一个事件,并传递一个数据。
然后在 b 组件中,通过钩子函数 createda组件创建的时候就通过this.$root.bus.$on('lala',function(value){}) 去监听这个lala事件


    <div id="app">
        <a-component></a-component>
        <b-component></b-component>
    </div>


    <script>
        Vue.component('a-component', {
            template: '<div><button @click="aHandle">点击我向B组件传递数据</button></div>',
            data() {
                return {
                    aaa: '我是A的内容'
                }
            },
            methods: {
                aHandle() {
                    //this.$root 表示的是根组件
                    this.$root.bbb.$emit('lala', this.aaa)
                }
            }
        })
        Vue.component('b-component', {
            template: '<div>我是B组件</div>',
            created() {
                //a 组件在创建实例的时候就监听事件--lala事件
                this.$root.bbb.$on('lala', function (value) {
                    alert(value)
                })
            }
        })


        let app = new Vue({
            el: '#app',
            data: {
                bbb: new Vue()
            }
        })
    </script>


父链、子链

父链:this.$parent

Vue.component('a-component', {
  template: '<button @click="setFatherData">通过点击我修改父组件的数据</button>',
  methods: {
      setFatherData() {
          //拿到父组件中的 msg ,对其进行修改
          this.$parent.msg = '数据已经修改了'
       }
  })


//父链的父链就是 this.$parent.$parent

子链:this.$children
提供了为子组件提供索引的方法,用特殊的属性ref为其增加一个索引

<div id="app">
   <a-component ref="a"></a-component>
   <b-component ref="b"></b-component>
   <c-component ref="c"></c-component>
   ---{{formChild}}
   <button @click="getChildData">我是父组件的按钮,点击我拿到子组件的内容</button>
</div>

    <script>
        Vue.component('a-component', {
            template: '<div>我是a组件</div>',
            data() {
                return {
                    msg: '我是a组件的内容'
                }
            }
        })
        Vue.component('b-component', {
            template: '<div>我是b组件</div>',
            data() {
                return {
                    msg: '我是b组件的内容'
                }
            }
        })
        Vue.component('c-component', {
            template: '<div>我是c组件</div>',
            data() {
                return {
                    msg: '我是c组件的内容'
                }
            }
        })


        let app = new Vue({
            el: '#app',
            data: {
                formChild: '还未拿到内容'
            },
            methods: {
                getChildData() {
                    //这个方法用来拿子组件中的内容,但是子组件不止一个
                    //所以用到 ref 属性为子组件加一个索引
                    //在需要拿到子组件的内容时直接通过 this.refs.索引名 就可以了
                    this.formChild = this.$refs.c.msg
                }
            }
        })
    </script>
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。