Vue3 setup组件的传参--父传子,子传父(setup参数)

2,015 阅读3分钟

一. 前言

vue3的组件传参(父传子,子传父)有两种方式:

1. setup参数

  1. 语法糖(juejin.cn/post/743221…)

与vue2组件的传参有相似,不详细的地方可先看vue2的传参方式(vue2父传子,vue2子传父)

二.准备工作--组件的引入

1 创建两个组件(父组件,子组件)

image.png

2 组件的引入

在js中引入(选择ts语言,vue3的)

image.png

import son from "./son.vue"

image.png

3 注册组件

注册命名在vue2组件的传参中注册组件和最后图片有关变量名相对应

  components:{
    // 2 注册组件
    son //缩写的形式
  },

image.png

4 使用组件

<son></son>

三.开始传参

1.父传子

(1) 在父组件中定义变量

在setup中定义变量

    let msg1 = ref("我是父组件的msg1")
    let msg2 = ref("我是父组件的msg2")

image.png

(2) 传参

方法一:给子组件绑定自定义属性,props
<son :msg1="msg1" :msg2="msg2"></son>

image.png 在子组件中接收数据

props:{
    msg1:{
      type:String
    }
  },

这里面的msg1就是自定义的属性名 image.png

方法二:attrs

在setup中有这个方法

image.png

2.子传父

(1) 在子组件中定义变量,在子组件上绑定自定义方法

在setup中定义变量

    let obj = ref({
      name:"张三",
      sex:"男"
    })

子组件上绑定自定义方法,@xsj:自定义方法名

<son @xsj="handleXsj"></son>
方法一:emit

子组件发送数据 image.png 父组件接收数据

image.png 纠错:s.value:要加value,不加value就不是响应式数据,他就无法渲染到页面中

方法二:插槽传参

子组件发送数据

    <!-- 插槽名字name,绑定了一个变量 -->
    <slot name="abc" :obj1="obj"></slot>

image.png 父组件接收数据

      <!-- v-solt:起的名字="接受的参数" -->
      <template v-slot:abc="props">
        <p>
          插槽接收数据:{{ props.obj1 }}
        </p>
      </template>

image.png

*****注意:在setup中所以定义的变量,要想使用必须return出去

image.png

四.全代码展示

1 父组件

<template>
  <div class="father">
    <h1>父组件</h1>
    <div>
      <button @click="handleClick">更新数据</button>
      <p>父组件中的msg1:{{ msg1 }}</p>
      <p>子传父接收数据:{{ s }}</p>
    </div>
    <!-- 3 使用组件 -->
    <!-- 4 给子组件绑定自定义属性父传子 -->
    <son :msg1="msg1" :msg2="msg2" @xsj="handleXsj">
      <!-- v-solt:起的名字="接受的参数" -->
      <template v-slot:abc="props">
        <p>
          插槽接收数据:{{ props.obj1 }}
        </p>
      </template>

    </son>
  </div>
</template>
sc
<script lang="ts">
// 1 引入子组件
import son from "./son.vue"
import { defineComponent,ref } from 'vue'

export default defineComponent({
  components:{
    // 2 注册组件
    son
  },
  setup() {
    let msg1 = ref("我是父组件的msg1")
    let msg2 = ref("我是父组件的msg2")
    let handleClick = ()=>{
      msg1.value+="1"
    }
    let s=ref({})
    // 子传父接收数据
    let handleXsj = (val:any)=>{
      console.log(val,"接收数据");
      // 将接收的数据赋值给s
      s.value=val
    }
    return{
      msg1,
      msg2,
      s,
      handleClick,
      handleXsj
    }
  },
})
</script>

<style lang="scss" scoped>
  .father{
    padding: 20px;
    background: pink;
  }
</style>

2 子组件

<template>
  <div class="son">
    <h1>子组件</h1>
    <p>接收父组件中的参数:{{ msg1 }}</p>
    <!-- 插槽名字name,绑定了一个变量 -->
    <slot name="abc" :obj1="obj"></slot>
  </div>
</template>
<script lang="ts">
import { defineComponent,ref } from 'vue'

export default defineComponent({
  props:{
    msg1:{
      type:String
    }
  },

  /*
    setup(props,context):
      参数1:props是个对象,这个对象存着父组件向子组件传递的数据
      参数2:context是一个对象,这个对象里面有三个参数
        attrs:相当于vue2里面的this.$attrs,可以获取父组件中给子组件绑定的自定义属性,注意与props冲突
        emit:相当于vue2里面的this.$emit,子传父
        slots:插槽传参
  */ 
//  {msg1,msg2}等价与props 解构赋值
  setup({msg1},{attrs,emit,slots}) {
    console.log(msg1,"props");
    console.log(attrs.msg2,"attrs");
    let obj = ref({
      name:"张三",
      sex:"男"
    })

    // 子传父
    emit("xsj",obj.value)
    return {
      obj
    }
  },
})
</script>

<style lang="scss" scoped>
  .son{
    padding: 20px;
    background: yellow;
  }
</style>