zoukankan      html  css  js  c++  java
  • vue 2.x 之子组件内调用父组件的方法

    日常开发者经常会遇到多层级嵌套组件,并且需要在最里面的子组件触发最外面的父组件事件,这种情况下当然最好的做法其实还是使用Vuex进行管理,如果你的项目使用Vuex进行管理了,后面就没必要看了。Vuex的相关内容请自行百度查阅。

    第一种:直接在子组件中通过this.$parent.event来调用父组件的方法
    这种方式可以无限级别的向上找父级,例如:this.$parent.$parent.$parent.$parent.event,子组件也不需要props属性接收父组件的方法,但是多层级的时候容易搞乱层级,.$parent太多了

    父组件

    <template>
      <div>
        <child></child>
      </div>
    </template>
    <script>
      import child from '@/components/child';
      export default {
        components: {
          child
        },
        methods: {
          fatherMethod() {
            console.log('fatherMethod');
          }
        }
      };
    </script>
    

    子组件

    <template>
      <div>
        <button @click="childMethod">点击</button>
      </div>
    </template>
    <script>
      export default {
        methods: {
          childMethod() {
            this.$parent.fatherMethod();
          }
        }
      };
    </script>
    

    第二种:父组件把方法传入子组件中,在子组件里直接调用这个方法
    父组件内调用子组件的时候需要显示的传入方法(注意:这里是用的:传入方法),子组件还需要通过props接收父组件传来的方法,否则也不可以调用,另外就是多层级的时候需要一层一层的往下传,这时候就比较繁琐

    父组件

    <template>
      <div>
        <child :fatherMethod="fatherMethod"></child>
      </div>
    </template>
    <script>
      import child from '@/components/child';
      export default {
        components: {
          child
        },
        methods: {
          fatherMethod() {
            console.log('fatherMethod');
          }
        }
      };
    </script>
    

    子组件

    <template>
      <div>
        <button @click="childMethod">点击</button>
      </div>
    </template>
    <script>
      export default {
        props: {
          fatherMethod: {
            type: Function,
            default: null
          }
        },
        methods: {
          childMethod() {
            if (this.fatherMethod) {
              this.fatherMethod();
            }
          }
        }
      };
    </script>
    

    第三种:子组件里用$emit向父组件触发一个事件名(注意:这里是用的@传入方法),父组件监听这个事件名就行了,子组件不需要通过props接收父组件传来的方法,否则也不可以调用,这种最好向上传递一层父级,否则也需要层层传递

    父组件

    <template>
      <div>
        <child @fatherMethod="fatherMethod"></child>
      </div>
    </template>
    <script>
      import child from '@/components/child';
      export default {
        components: {
          child
        },
        methods: {
          fatherMethod() {
            console.log('fatherMethod');
          }
        }
      };
    </script>
    

    子组件

    <template>
      <div>
        <button @click="childMethod">点击</button>
      </div>
    </template>
    <script>
      export default {
        methods: {
          childMethod() {
            this.$emit('fatherMethod');
          }
        }
      };
    </script>
    

    第四种:使用$emit$on 配合传递事件
    如果仅仅是父子一层,传递事件就使用第三种就可以了,如果多层传递或者是兄弟组件,还可以使用$emit$on 配合,其原理就是new 一个vue实例,然后在父子组件引入这个实例,这样在子组件触发的事件就会在父组件监听到了,这就是网上说的eventBus。

    新建一个bus.js

    import Vue from 'vue';
    export default new Vue();
    

    在父子组件分别引入这个bus.js

    import eventBus from 'bus';
    
    

    在子组件触发事件

      export default {
        methods: {
          childMethod() {
            eventBus.$emit('fatherMethod');
          }
        }
      };
    

    在父组件监听事件

      export default {
        mounted() {
          //如果出现多次监听,肯定是没有解绑,可以在监听之前解绑,也可以在进入到这个路由或者渲染组件时候解绑一下就好了
          eventBus.$off('fatherMethod');
          eventBus.$on('fatherMethod');
        }
      };
    

    当然如果你觉得建一个bus.js文件多余的话,可以在main.js里把bus加到原型上

    //vue原型链挂载总线
    Vue.prototype.eventBus = new Vue();
    

    加到原型上的好处就是全局都可以使用了

    this.eventBus.$emit('fatherMethod');
    this.eventBus.$on('fatherMethod');
    
  • 相关阅读:
    Network(树形dp)洛谷2899
    2590 树的统计
    LCT 最小生成树
    几种贪心小结
    snmp
    div页面跳转
    2017.11.2总结,回顾及成果
    2017.11.1知识总结及回顾
    check,form,单选框与复选框总结
    HTML空格字符
  • 原文地址:https://www.cnblogs.com/jiaoshou/p/13706943.html
Copyright © 2011-2022 走看看