Vue 父子组件传参、插槽

setup 函数中有两个主要的参数:props、context 。

props 用于接收父组件传递过来的数据,父传子。

context 指的是 setup 的上下文,它有三个属性:attrs、slots、emit 。

attrs 用于:当父组件传递过来的数据,没有被 props 接收时,数据就会存放在 attrs 属性中。

slots 用于:接收父组件传递过来的插槽内容,相当于 vue2 中的 `this.$slots` 。

emit 用于:创建自定义事件函数,子传父。相当于 vue2 中的 `this.$emit` 。

setup 函数中的 props 参数【父传子】

父组件

html 复制代码
<template>
    <h1>我是父组件</h1>
    <hr />
    <!-- 3.使用子组件,并通过自定义属性传递数据 -->
    <Child :name="info.name" sex="男" :age="info.age"></Child>
</template>

<script>
import { reactive } from 'vue';
// 1.引入子组件
import Child from '../components/Child.vue';
export default {
    name: "Parent",
    // 2.注册子组件
    components: { Child },
    setup() {
        let info = reactive({
            name: "张三",
            age: 18
        })
        // 返回数据
        return { info }
    }
}
</script>

子组件

html 复制代码
<template>
  <h1>我是子组件</h1>
  <p>姓名:{{ props.name }}</p>
  <p>性别:{{ props.sex }}</p>
  <p>年龄:{{ props.age }}</p>
</template>

<script>
export default {
  name: "Child",
  // 接收数据,未接收的数据不会在 props 参数中显示
  props: ['name', 'sex'],
  setup(props, context) {
    console.log(props);
    // 返回数据
    return { props }
  }
}
</script>

效果

props 参数的几种接收方式

无限制接收

javascript 复制代码
props: ['name', 'sex', 'age']

限制数据类型接收

javascript 复制代码
props: {
  name: String,
  age: Number,
  sex: String
}

限制数据类型、默认值、是否必填接收:

javascript 复制代码
props: {
  name: {
    type: String,
    required: true // 是否必填
  },
  age: {
    type: Number,
    required: true // 是否必填
  },
  sex: {
    type: String,
    default: '保密' // 设置默认值
  }
}

context 参数中的 attrs 属性【子传父】

父组件:

html 复制代码
<template>
  <h1>我是子组件</h1>
  <p>姓名:{{ props.name }}</p>
  <p>性别:{{ props.sex }}</p>
  <p>年龄:{{ props.age }}</p>
</template>

<script>
export default {
  name: "Child",
  // 假设父组件传递了 name、age、sex 三个数据,props 只接收 name 数据
  props: ['name'],
  setup(props, context) {
    // 那么 props 未接收的数据会在 attrs 属性中显示
    console.log(context.attrs);
    // 返回数据
    return {
      props
    }
  }
}
</script>

效果:

context 参数中的 slots 属性【默认插槽】

父组件

html 复制代码
<template>
    <h1>我是父组件</h1>
    <hr />
    <Child>
        <p>姓名:{{ info.name }}</p>
        <p>年龄:{{ info.age }}</p>
    </Child>
</template>

<script>
import { reactive } from 'vue';
import Child from '../components/Child.vue';
export default {
    name: "Parent",
    components: { Child },
    setup() {
        let info = reactive({
            name: "张三",
            age: 18
        })
        // 返回数据
        return { info }
    }
}
</script>

子组件:

html 复制代码
<template>
  <h1>我是子组件</h1>
  <slot>默认值</slot>
</template>

<script>
export default {
  name: "Child",
  setup(props, context) {
    // 父组件传递过来的插槽内容,会存放在 slots 属性中
    console.log(context.slots);
  }
}
</script>

效果:

context 参数中的 emit 属性【子传父】

父组件

html 复制代码
<template>
    <h1>我是父组件</h1>
    <hr />
    <!-- 使用自定义事件 -->
    <Child @myEvent="myInfo"></Child>
</template>

<script>
import Child from '../components/Child.vue';
export default {
    name: "Parent",
    components: { Child },
    setup() {
        // 接收父组件传递的数据
        let myInfo = (value) => {
            alert(`我是父组件,我收到数据了,值为:${value}`);
        }
        // 返回数据
        return { myInfo }
    }
}
</script>

子组件:

html 复制代码
<template>
  <h1>我是子组件</h1>
  <button @click="test">往父组件中传递数据</button>
</template>

<script>
export default {
  name: "Child",
  // 声明自定义事件
  emits: ['myEvent'],
  setup(props, context) {
    let test = () => {
      // 调用自定义事件,语法为:context.emit('自定义事件', 值);
      context.emit('myEvent', 666);
    }
    // 返回数据
    return { test }
  }
}
</script>

效果

原创作者:吴小糖

创作时间:2023.10.26

相关推荐
奎叔12 分钟前
Flutter 异常处理体系:从捕获、转换到恢复
前端
心念枕惊14 分钟前
.NET CORE 授权进阶-角色、策略与动态权限实现
java·前端·.netcore
小徐_233317 分钟前
寓言故事一则:狗猛酒酸
前端·ai编程
xiaobaoyu35 分钟前
vue2+element开发中问题和解决方式
前端
KaMeidebaby36 分钟前
卡梅德生物技术快报 | 核酸适配体文库测序:核酸适配体文库测序的技术原理、实验流程与数据解析
前端·网络·数据库·人工智能·算法
Hilaku1 小时前
为什么在 2026 年,MPA(多页面应用)正在悄悄复辟?
前端·javascript·程序员
幸福小宝1 小时前
eslint和prettier
前端
anyup1 小时前
终于在今天入选了 Gitee GVP,这真值得庆祝~
前端·uni-app·开源
幸福小宝1 小时前
husky和lint-staged
前端
悟空瞎说1 小时前
iOS 高效绘图
javascript