Vue组件通信整理

1. 前言

组件化是Vue.js最突出的特征之一。Vue组件化为我们提供了一种抽象,让我们可以通过使用独立的可复用的组件来构建大型应用。而如何快速有效地实现组件间的通信,是我们在开发过程中经常会碰到以及使用到的技巧。这里我给大家介绍一下Vue组件间通信的几种方式。

2. 组件通信常用方式

  • props
  • $emit
  • bus 事件总线
  • vuex
  • $refs、$parent、$children

3. 组件通信具体实现

1. 父给子传值

使用props

//parent
<child :msg="message"></child>

//child
<script>
export default{
    props:['msg']
    //props:{ msg:String }
}
</script>
  • 扩展:使用sync修饰符,修改props中数据
//parent
<child :msg.sync="message"></child>

//child
 this.$emit('update:msg', this.changeValue);
2. 子给父传值

使用$emit

//child
 this.$emit('toParent', this.msg);

//parent
 <child @toParent="getChildMsg"></child>
3. 兄弟间传值
  • 结合使用props和$emit实现
    //child1  子传给父
    this.$emit('toParent', this.msg);
    
    //child2  接收父传过来的值
    export default {
      props: ['msg']
    };
    
    //parent  接收child1传过来的值 并传递给child2
    <child1 @toParent="getChildMsg"></child1>
    <child2 :msg="msg"></child2>
    
    methods: {
        getChildMsg(msg) {
        	this.msg = msg;
        }
    }
    
  • 通过$parent注册和监听事件
    //child1  子通过$emit注册事件
     methods: {
        sendMessage() {
          this.$parent.$emit('foo', this.msg);
        }
      }
      
    //child2 子通过$on监听事件
    mounted() {
        this.$parent.$on('foo', msg => {
          console.log(msg);
        });
      }
      
    //parent
    <button style="width:100px;height:30px" @click="sendMessage">
        sendMessage
    </button>
    
     methods: {
        sendMessage() {
          this.$refs.child1.sendMessage();
        }
      }
    
4. 祖先和后代间传值
  1. 使用provide/inject

    // 祖先通过provide传值
     provide() {
         return {
         	msg: '来自祖先的消息'
         }
     },
     
    //后代通过inject接收值  类似于props的方式
    inject: ['msg']  
    
  2. 使用$attrs$listeners

    • 需要在父组件中使用v-bind="$attrs" v-on="$listeners"。$attrs用于调用祖辈非props接收的参数,$listeners用于调用祖辈方法
  • index.vue(祖先)

    <template>
      <div>
        <comp-a :name="name" :age="age" :phone="phone" @study="study">
        </comp-a>
      </div>
    </template>
    <script>
    import CompA from './CompA.vue';
    export default {
      components: { CompA },
      data() {
        return {
          name: 'jack',
          age: 18,
          phone: 'iphone'
        };
      },
      methods: {
        study(parmas) {
          console.log('study');
        }
      }
    };
    </script>
    
  • compA.vue(parent)

    <template>
      <div>
        <comp-b v-bind="$attrs" v-on="$listeners"></comp-b>
      </div>
    </template>
    <script>
    import CompB from './CompB.vue';
    export default {
      components: { CompB },
      props: {
        name: {
          type: String,
          default: ''
        },
        age: {
          type: Number,
          default: 0
        }
      },
      mounted() {
        console.log('compA');
        console.log('attrs', this.$attrs);
        this.$listeners.study('compA');
      }
    };
    </script>
    
  • compB.vue(child)

    <template>
      <div>
      </div>
    </template>
    <script>
    export default {
      mounted() {
        console.log('compB');
        console.log('attrs', this.$attrs);
        console.log('this', this);
        // 调用祖先方法
        this.$listeners.study('compB');
      }
    };
    </script>
    

    console.log打印结果:

5. Vue-bus

Vue事件总线vue-bus简单使用

6. Vuex

Vuex笔记

posted @ 2021-05-27 20:58  Scorpioz_one  阅读(42)  评论(0编辑  收藏  举报