vue插槽与父子组件传值

10,831 阅读4分钟

1.父子组件之间的传值

子组件传值到父组件

子组件在向父组件传值的时候,主要是通过子组件通过$emit()函数派发出事件,然后再父组件中通过事件监听:

//比如定义了一个子组件<i-button>
<template>
  <button @click="handleClick">
    <slot></slot>
  </button>
</template>
<script>
  export default {
    methods: {
      handleClick () {
        this.$emit('on-click', {a:123});
      }
    }
  }
</script>
//这里的on-click是事件的名字,a是要传递的参数

//然后在父组件中监听
<i-button @on-click="sayhi">sayhi</i-button>

<script>
  export default {
        methods:{
         sayhi(b){
          console.log(b);  // Vue.js
        }
      }
  }
</script>
//注意这里的b只是用来接收子组件传递过来的对象,输入的是{a:123},并不会输出123,如果输出123可以写成b.a

父组件向子组件传值

父组件向子组件传值,主要是通过子组件的prop属性来接收父组件的数据:

//比如在父组件中声明传值
<i-button :title="titleData"></i-button>

data(){
    return{
      titleData:'hello props'
    }
},

//在子组件<i-button>中接收
<h3>{{title}}</h3>

props: ["title"],

//这里就会显示为<h3>helo props</h3>

或者使用props中声明的为对象的方式:

//在父组件中声明传值
<i-button :title="titleData"></i-button>

data(){
    return{
      titleData:'hello props'
    }
},

//在子组件<i-button>中接收
<h3>{{title}}</h3>

props: {
    title:{
        
    },
},

//这里也会显示为<h3>helo props</h3>

2.插槽传值,插槽的定义是子组件显示什么内容由父组件决定

插槽传值的基本用法:

比如定义了一个子组件<i-button>
<template>
  <button>
    <slot></slot>
  </button>
</template>

在父组件中使用
<i-button>按钮1<i-button>

这里就会显示成为
<button>按钮1<button>

给插槽起个名字:

//子组件
<template>
  <button>
    <slot name="icon"></slot>
    <slot>solot里面默认的内容</slot>
  </button>
</template>

//父组件
<i-button slot="icon">按钮1</i-button>
<i-button >按钮2</i-button>
<i-button ></i-button>

//这里解释一下
1.如果在父组件中使用的时候给slot赋值了名字,那么这里子组件就会显示<button>按钮1</button>
2.如果在父组件中没有赋值名字,但给了子组件要显示的内容,那么这里子组件就会显示<button>按钮2</button>
3.如果在父组件中没有赋值名字,也没有给了子组件要显示的内容,那么这里子组件就会显示默认的内容<button>solot里面默认的内容</button>

作用域插槽:

如果我们在父组件中这样写:

<i-button >{{titleData}}</i-button>

这里的titleData是父组件中的数据,这样写是不能够正常工作的,因为titleData是父组件的数据,子组件并不能获取到,这个时候就需要用到我们的作用域插槽了。

父组件来访问子组件的数据:

//父组件
<i-button >
  <template  slot-scope="parentName">{{parentName.childrenName}}</template>
</i-button>

//子组件<i-button>
<template>
  <button>
    <slot :childrenName="childrenData"></slot>
  </button>
</template>

data(){
    return{
      childrenData:"hello slot-scope"
    }
},

//这里父组件就会拿到子组件childrenData的值,显示为<button>hello slot-scope</button>
//解释下,parentName可以理解是父组件与子组件之间的标识,childrenName才是真正绑定的数据

如果我们从父组件中传值过去到子组件中显示,就需要利用父子组件之间传值的方法了:

//父组件
<i-button :parenDataName="parentData">
  <template  slot-scope="parentName">{{parentName.childrenName}}</template>
</i-button>

data(){
    return{
      parentData:"hello slot-scope parent"
    }
  },

//子组件<i-button>
<template>
  <button>
    <slot :childrenName="childrenData"></slot>
  </button>
  <button>
    <slot :childrenName="parentDataName"></slot>
  </button>
</template>

props: {
    parentDataName:{}
},
data(){
    return{
      childrenData:"hello slot-scope children"
    }
},

//这里一个是直接访问子组件中的值,一个是先自己传递过去之后再访问子组件中的值

区别

现在我们已经知道了插槽与父子组件之间传值的基本用法,那么他们之间有什么区别呢?我概况为以下几点

1.插槽之间的传值,插槽要显示的内容是写在父组件中的,也就是父组件中的数据是写在自己的组件里。
2.而父子组件之间的传值,是在当前组件拿到了数据之后,然后才在当自己的组件中显示。
3.如果说他们之间有什么联系的话,插槽传值,其实类似于父组件向子组件传值。而插槽默认值的写法又像是子组件向父组件传值,只是如果父组件有传值过来,会被覆盖掉了而已。