Vue组件之间的传参方式小总结

9 篇文章 1 订阅
4 篇文章 0 订阅

学习vue的组件,可能很多人已经了解了组件的创建注册使用,但是随之而来的就是组件之间的通信,父子组件怎么传? 兄弟组件怎么传? 不是父子组件又怎么传?

接下来介绍几种组件之间的传参方式,也是很容易面试被问到的.

1.父传子用props

父组件传递参数给子组件的时候,可以使用props这个属性

 <div id="app">
    <cpn :cmsg="msg"></cpn>
  </div>
  <template id="cpn">
    <div>
      {{cmsg}}
    </div>
  </template>
  <script src="../vue.js"></script>
  <script>
    var cpn = {
      template:'#cpn',

      // props:['cmsg']  props的格式有数组形式和对象形式
      props:{
        cmsg:{
          type:String,
          default:'1000'
        }
      },
      // 如果是类型是Array/Object deafult必须是一个函数dafault(){} 例如 ↓
      // props:{
      //   list:{
      //     type:Array,
      //     default() {
      //       return []
      //     }
      //   }
      // }
    }
    var app = new Vue({
      el:'#app',
      data: {
        msg:'我是父组件的消息'
      },
      components:{
        cpn
      }
    })
  </script>

在这里插入图片描述
运行结果在这里插入图片描述

2.子传父用$emit

emit是发射的意思,也就是,子组件需要向父组件传递数据使用emit来发射一个自定义事件,在子组件上绑定该自定义事件,同时在父组件上有个对应的事件进行双向绑定事件,直接上代码.

 <div id="app">
    {{aaa}}
    <cpn @itemfun='parentEvent'></cpn>
  </div>

  <template id="cpn">
    <div>
      <!-- 这里就需要绑定一个事件 -->
      <button @click="btnClick">点击按钮发送自己的消息给俺爸爸</button>
    </div>
  </template>
  <script src="../vue.js"></script>
  <script>
    var cpn = {
      template:'#cpn',
      data() {
        return{
          aa:'我是子组件上的信息'
        }
      },
      methods: {
        btnClick(){          
          this.$emit('itemfun',this.aa)
        }
      },
    }
    var app = new Vue({//根组件,也相当于是父组件
      el:'#app',
      data: {
        aaa:'我将要被替换'
      },
      methods: {
        parentEvent(val) {
          console.log(val);
          this.aaa = val
        }
      },
      components:{
        cpn
      }
    })
  </script>

在这里插入图片描述
运行结果:
在这里插入图片描述

3.子访问父相互传使用 $refs

这是一重灰常人性化的 传参方式,其实也就是拿参数的一种简便方式 ,ref属性被用来给元素或者组件注册引用信息,引用信息会注册在父组件的$ref对象上(如果ref放在对象上,拿到的是原生节点,ref放在组件上,拿到的就是组件实例),我们先来看一下代码
我已经注册了两个组件,并且在vue根组件上使用,绑定了ref
在这里插入图片描述

我们可以去vue实例里面的生命周期函数mounted里面打印一下这个 this.$fefs ,看看能打印出什么信息.

	mounted() {
        console.log(this.$refs)
    },

可以看大在控制台打印出了两个子组件实例,而且是一数组的方式存储,相当于ref='键名’
取出来的话使用this.$refs.aaa 这样就可以拿到这个组件实例
在这里插入图片描述
通过对象引用的方式就可以拿到不同组件实例上的不同参数和方法
在这里插入图片描述
这里子不能访问父.↓
在这里插入图片描述
在这里插入图片描述

4.父子相互访问 $parent / $root / $children

顾明思议,this.$parent 拿到的就是当前实例组件的父组件,记住是父组件,不是父组件之上的组件,他爸爸的爸爸已经是爷爷了,不是父亲了.而 this. $root 拿到的是根组件,也就是var app = new Vue({})这个根组件实例.

查看$parent的内容
在这里插入图片描述
一起打印看看
在这里插入图片描述

5. 非父子组件(兄弟)组件之间的通信,EventBus,事件总线.

在vue中 是通过单独的事件中心来管理非父子组件,也就是兄弟组件之间的通信
在这里插入图片描述

1.建立事件中心

var EventBus = new Vue()

2.使用事件中心发射自定义事件

eventBus.$emit('自定义事件名',传递的数据)

3.使用事件中心接受数据

eventBus.$on('自定义事件名',[,callback])

下面看示例图
在这里插入图片描述

5. provide 和 inject 跨级传参

这两个参数是一起起作用的,允许一个祖先组件向起所有子孙后代注入一个依赖,不管组件层次有多深,都能建立起关系
provide:是一个对象,返回对象的一个函数,里面包含要给子孙属性的东西,也就是属性和属性值
inject: 一个字符串数组,或者是一个对象,属性值可以是一个对象,包含from和default默认值
from表示在可用的注入内容中收缩用的key,default当然也是默认值

6. 作用域插槽

我們先來想一个需求,假如子组件中有一组数据,但是想以不同的形式展示在父组件中,处理使用$emit等传参方式,也可以使用作用域插槽.

在这里插入图片描述
代码附上:

<div id="app"> 
  <!-- 假如第一个组件里我们想以列表的形式展示 -->
    <cpn v-slot='aa'>
      <slot><ul v-for='item in aa.data'><li>{{item}}</li></ul></slot>
    </cpn>
     <!-- 假如第二个组件里我们想以' - ' 的方式来连接book数组里面的内容 -->
    <cpn v-slot='bb'>
      <span>{{bb.data.join('-')}}</span>
    </cpn>

  </div>
  <template id="cpn">
    <div>
    <span>
    <!-- 这里相当于给book起个别名叫做data -->
      <slot :data='book'></slot>
    </span>
    </div>
  </template>
  <script src="../vue.js"></script>
  <script>

    var cpn = {
      template:'#cpn',
      data() {
        return {
          book:['飞鸽传书','天山雪莲','鲨鱼','翻身']
        }
      }
    }   

    var app = new Vue({
      el:'#app',
      data: {
        
      },
      components:{
        cpn
      }
    })
  </script>

7.非父子组件又不同层次之间的 组件间的传值.

provide/inject:简单的来说就是在父组件中通过provider来提供变量,然后在子组件中通过inject来注入变量。
需要注意的是这里不论子组件有多深,只要调用了inject那么就可以注入provider中的数据。而不是局限于只能从当前父组件的prop属性来获取数据

//父组件
<template>
  <div>
<childOne></childOne>
  </div>
</template>

<script>
  import childOne from '../components/test/ChildOne'
  export default {
    name: "Parent",
    provide: {
      for: "demo"
    },
    components:{
      childOne
    }
  }

子组件一

<template>
  <div>
    {{demo}}
    <childtwo></childtwo>
  </div>
</template>

<script>
  import childtwo from './ChildTwo'
  export default {
    name: "childOne",
    inject: ['for'],
    data() {
      return {
        demo: this.for
      }
    },
    components: {
      childtwo
    }
  }
</script>

子组件二

<template>
  <div>
    {{demo}}
  </div>
</template>

<script>
  export default {
    name: "",
    inject: ['for'],
    data() {
      return {
        demo: this.for
      }
    }
  }
</script>

运行结果:
在这里插入图片描述
最后一个传参的代码是搬运的,也是很清晰明了.

这是一篇拖更了好久的文章,两三个星期前就差点写好了,忙活忙活就忘记补全发出去了,害…

各自努力,顶峰相见.加油

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值