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');
    
  • 相关阅读:
    git代码合并与冲突
    jQuery 事件方法---vvvv0
    原生JS获取HTML DOM元素的方法----------c
    JQuery获取元素的方法总结--ccc
    zookeeper[5] zookeeper集群配置及伪集群配置
    zookeeper[4] 安装windows zookeeper,及问题处理
    zookeeper[3] zookeeper API开发注意事项总结
    zookeeper[2] zookeeper原理(转)
    zookeeper[1] (转)ZooKeeper Programmer's Guide(zookeeper编程向导)---中文
    Java[1] Java学习书籍汇总(转)
  • 原文地址:https://www.cnblogs.com/jiaoshou/p/13706943.html
Copyright © 2011-2022 走看看