vue2组件之间的通信方式

168 阅读2分钟
组件之间通信

(1)、props(父组件 => 子组件)

props可以实现父组件向子组件传递数据,这也是比较常用的方式。但是子组件收到数据之后,如果为简单数据类型不能直接修改父组件中的数据,这样会报错;如果为复杂数据类型,vue中不建议直接修改。

//子组件
<template>
    <div>
        <p>{{week}}</p>
        <ul>
            <li v-for="item in list" :key="item">{{item}}</li>
        </ul>
   </div>
</template>
<script>
export default {
//数组方式接收
    //props: ['week','list'],
    props:{
  // 写法二 用对象接收,可以限定接收的数据类型、设置默认值等;其中props 的 type 值可以为:'String'、'Number'、'Boolean'、'Array'、'Object'、'Date'、'Function'等
  list:{
  type:['String']
  }
    }
    data() {
        return {
        }
    },
    components:{
    },
}
</script>

// 父组件
<template>
   <children :week="week" :list="pannel"></children>
</template>
<script>
import children from './components/son.vue'
export default {
    data() {
        return {
            week: "周末安排",
            pannel: ['学习', '睡觉', '吃饭']
        }
    },
    components:{
       children
    },
}
</script>

注意:props的更新数据会向下流动到子组件的,当父组件数据发生改变的时候,子组件中的props都将会变成最新的值。因此,props是属于单向下行绑定的

(2)、$emit(子组件 => 父组件)

$emit可以实现子组件向父组件传值。在子组件当中,想要修改父组件的状态时会通过$emit方法触发自定义事件,父组件对应监听子组件自定义事件的回调函数就会被触发,然后获取到子组件传递过来的数据。

// 子组件
<template>
    <div>
        <p>{{msg}}</p>
        
   </div>
</template>
<script>
export default {
    data() {
        return {
           msg: "这是父组件shu据" 
        }
    },
    components:{
    },
    mounted() {
    },
    methods: {
      getList(){
        this.$emit('sendMsg',this.msg)
      }
    }
}
</script>
// 父组件
<template>
   <children @getList="sendMsg"></children>
</template>
<script>
import children from './components/son.vue'
export default {
    data() {
        return {
        }
    },
    components:{
       children
    },
    mounted() {
    },
    methods: {
      sendMsg(val){
        console.log(val);
      }
    }
}
</script>

(3)、.sync(父子组件双向通信)
.sync可以帮我们实现父子组件的双向绑定,即子组件接收到父组件的数据时,也可以进行修改,并且会同时修改父组件里面的数据

// 正常父传子: <son :a="num" :b="num2"></son> 
// 加上sync之后父传子: <son :a.sync="num" .b.sync="num2"></son> 
// 它等价于 <son :a="num" @update:a="val=>num=val" :b="num2" @update:b="val=>num2=val"></son>

注意:$emit所调用的事件名必须是update:属性名,事件名写错它是不会报错,但是也不会有改变

(4)、v-model(父子组件双向通信)
v-model和.sync一样,v-model的本质上是一个语法糖,可以实现将父组件传给子组件的数据为双向绑定
v-model日常习惯写法:

<input v-model="val" type="text">

完整写法:

<input :value="val" @input="val=$event.target.value" />

注意:一般情况下父向子传值,子组件中是不能直接修改的,在这里我们在子组件中直接修改这个值会进行报错。
所以我们需要在父组件上添加自定义事件,通过在子组件中使用$emit('自定义事件名',值)的方法将值传入父组件。

(5)、ref
如果在普通的DOM元素上,引用指向的就是该DOM元素。如果在子组件上,引用的指向就是子组件实例,在父组件代码中,通过在子组件上标签上设置属性ref,可在this.$refs中获取到子组件对象,以此调用子组件内的变量和方法,触发子组件的变化

image.png

(6)、$children和$parent
$children可以获取到当前组件的所有子组件(操作子组件的数据与方法),返回的是一个组件集合。 $parent既可以接受父组件数据,又可以修改父组件数据,是双向的;它还可以调用父组件的方法。

btn(){ //获取父组件age值 
console.log(this.$parent.age); 
//修改父组件name值 
this.$parent.age ="18"; 
//调用父组件方法
### this.$parent.addFn(); }