Vue2.x中,父子组件通信


有这么一个情况,在父组件中,使用了子组件,现在想将父中的某些值传给子,或者将子中的某些值传给父。
为了解决以上问题,通常采用的是props来实现。props的值可以是两种:字符串数组、对象;

父传子

这里首先介绍数组的情况:
在子组件中,定义props:

<template>
  <div>{
   
   {parentStr}}</div>
</template>
<script>
export default {
     
     
  props: ["parentStr"]
};
</script>

然后在父组件中,使用该组件的时候,传入这个值就可以了:

<template>
 	<layout_head parentStr="这个是父组件传递的信息"/>
 </template>
 <script>
import layout_head from "./head.vue";
export default {
     
     
  components: {
     
      aside_menu ,layout_head}
};
</script>

对象:

通常你希望每个props都有指定的值类型。这时,可以以对象形式列出props ,这些属性的名称和值分别是props各自的名称和类型:

 props: {
    
    
   title: String,
   likes: Number,
   isPublished: Boolean,
   commentIds: Array,
   author: Object
 }

注意

  • 如果说有多个数据需要传输,则在props中定义多个项,然后父组件在使用这个子组件的时候,设置好这些值就可以了。
  • html中不区分大小写,所以,当使用DOM模版时,驼峰命令的props名称要为短横线分隔命名:myCom 写成my-com;
  • 以上例子中,父传的值是写死的,也可以是动态的,使用v-bind来实现:<layout_head :parentStr=“str”/>
  • 如果直接传递数字、布尔值、数组、对象,而不是使用v-bind,那么传递的仅仅是字符串

单向数据

有两点需要明白:

  1. 在Vue2.x中,数据的传递是单向的,也就是说,只能是父传给子,不能子传给父。
  2. 当时在JS中,对象和数组都是引用类型,指向同一个空间;

由于这两点,所以,直接修改父传递的值,就会由于第二点原因,造成违背第一点规则。所以直接修改这个传递的值,就会报错。
所以,如果父传的值,在子中,需要修改,通常的做法就是:(不直接操作传入的值)

export default {
    
    
	props: ["parentStr"],
	data() {
    
    
	  return {
    
    
	    sub_parentStr: this.parentStr
	  };
	}
};

子传父

在了解了单向数据之后,明白了在Vue2.x中,只允许父传子,子传父是不允许的。
如果真的想在子中传数据的父中,可以使用$emit方式。
记住:单向数据的原则不能违背,所以,子传父,严格的来说,传的是子自己的一些信息,而不是父传的信息。
当然,可以使用一个变量来保存父传的信息,然后将这个变量传会给父,父在赋值给之前的那个变量:
子组件中的写法:

<script>
export default {
     
     
  props: ["collapsed"],
  data() {
     
     
    return {
     
     
      sub_collapsed: this.collapsed
    };
  },
  methods: {
     
     
    //改变sub_collapsed的值
    sendCollapsed: function() {
     
     
      this.sub_collapsed = !this.sub_collapsed;
      //讲sub_collapsed的值,传递给父组件
      this.$emit("receiveCollapsed", this.sub_collapsed);
    } //~end sendCollapsed
  }
};
</script>

父组件中的写法:

...
 <layout_head :collapsed="collapsed" @receiveCollapsed="receiveCollapsed" />
 ...
 <script>
import layout_head from "./head.vue";
export default {
     
     
  data() {
     
     
    return {
     
     
      collapsed: false
    };
  },
  components: {
     
      layout_head },
  methods: {
     
     
	//从子组件中,接收collapsed的变化
    receiveCollapsed: function(sub_collapsed) {
     
     
      this.collapsed = sub_collapsed;
    }//~end receiveCollapsed
  }
};
</script>

最后,需要说明的是:$emit()方法的第一个参数是自定义事件(父组件中,调用子组件的时候,写的那个值),然后第二个参数(或者第n个参数,也有可能没有)都是要传递的值。

v-model方式

有一种更加简便的方式:使用v-model
基于以上方法,只需要在子组件中,修改:

this.$emit("input", this.sub_collapsed);//这里的input是固定的

说明:这个input是一个特殊的事件名,不需要在父组件中进行@input="receiveCollapsed"的操作。
然后父组件在调用子组件的时候:

 <layout_head :collapsed="collapsed" v-model="collapsed" />

这个时候的父组件,都不需要定义receiveCollapsed方法了。
两种方式的结果是一样的,v-model的方式虽然简单,但是仅仅适合赋值的情况。

猜你喜欢

转载自blog.csdn.net/fyk844645164/article/details/100540990