Vue3 组件和插槽

文章介绍了Vue3中的组件基础知识,包括如何定义和使用组件,以及组件间的通信方式。内容涵盖根组件的创建、组件的嵌套,以及父子组件和根组件之间的访问。此外,详细阐述了插槽的使用,包括默认插槽、具名插槽和作用域插槽,展示了如何在组件中插入和使用自定义内容。
摘要由CSDN通过智能技术生成

Vue3 组件和插槽

组件基础

组件允许我们将 UI 划分为独立的、可重用的部分,并且可以对每个部分进行单独的思考。在实际应用中,组件常常被组织成层层嵌套的树状结构:

在这里插入图片描述

根组件

我们传入 createApp 的对象实际上是一个组件,每个应用都需要一个“根组件”,其他组件将作为其子组件。

如果你使用的是单文件组件,我们可以直接从另一个文件中导入根组件。

import { createApp } from 'vue'
// 从一个单文件组件中导入根组件
import App from './App.vue'

const app = createApp(App)

简单使用

定义组件

src/components目录下,定义 Content.vueHello.vue 2个组件:

Hello.vue组件

<template>
    <h3>我是Hello.vue</h3>
</template>

Content.vue组件

父组件可以嵌套子组件。

<script>
import Hello from "./Hello.vue"
export default {
    components: {
        Hello
    }
}
</script>

<template>
    <Hello></Hello>
    <h2>我是Content.vue</h2>
    <Hello></Hello>
</template>

使用组件

<script>
import Content from "../components/Content.vue"
export default { 
    components: {
        Content
    }
}
</script>

<template>
    <Content></Content>
</template>

在这里插入图片描述

父子访问

父组件访问子组件

<script>
import Child3 from "./Child3.vue"
export default {
    //挂载
    mounted() {
        // 第二步:通过`$refs`获取子组件数据
        console.log(this.$refs);
        // 获取子组件的name/age/sex数据:
        console.log(this.$refs.child3.name);
        console.log(this.$refs.child3.age);
        console.log(this.$refs.child3.sex);
    },
    //组件
    components: {
        Child3
    }
}
</script>

<template>
    <h2>父组件</h2>
    <!-- 第一步:通过`ref`注册引用信息 -->
    <Child3 ref="child3"></Child3>
    <p ref="p"></p>
</template>

子组件访问父组件

在开发中尽量少用$parent

<script>
export default {
    data() {
        return {
            name: "小明",
            age: 18,
            sex: true
        }
    },
    mounted() {
        // 通过`$parent`获取父组件
        console.log("父组件:", this.$parent);
        // 获取父组件数据
        console.log("父组件list:", this.$parent.list);
    }
}
</script>

<template>
    <h3>子组件3</h3>
</template>

访问根组件

<script>
export default {
    mounted() {
        // 通过`$root`获取根组件
        console.log("根组件:", this.$root);
        // 访问根组件数据
        console.log("根组件rootName:", this.$root.rootName);
    }
}
</script>

<template>
    <h3>子组件3</h3>
</template>

插槽

使用插槽

只能使用单个插槽。

  • <slot>元素是一个插槽出口。表示父元素的插槽内容在哪里渲染。

定义插槽组件:MySlot.vue

<template>
  <h2>使用插槽</h2>
  <div>
    <!-- slot占位 -->
    <slot></slot>
  </div>
</template>

使用插槽

<script>
import MySlot from "../components/MySlot.vue"
export default {
    //组件
    components: {
        MySlot
    }
}
</script>

<template>
    <MySlot>
        <!-- 使用插槽 -->
        <button>按钮</button>
    </MySlot>
    <MySlot>
        <input type="text" placeholder="请输入123">
        <input type="text" placeholder="请输入abc">
    </MySlot>
</template>

在这里插入图片描述

具名插槽

可以定义和使用多个插槽。

  • <slot>元素中定义name属性,用于给插槽分配唯一的id。

定义具名插槽组件:MyMultiSlot.vue

<template>
  <h2>使用具名插槽</h2>
  <div>
    <slot name="a"></slot>
    <slot name="b"></slot>
    <slot name="c"></slot>
  </div>
</template>

使用具名插槽

<script>
import MyMultiSlot from "../components/MyMultiSlot.vue"
export default {
    //组件
    components: {
        MyMultiSlot
    }
}
</script>

<template>
    <MyMultiSlot>
        <template v-slot:a>
            <button>按钮一</button>
        </template>
        <template v-slot:b>
            <button>按钮二</button>
        </template>
        <template v-slot:c>
            <button>按钮三</button>
        </template>
    </MyMultiSlot>
</template>

在这里插入图片描述

默认值插槽

在外部没有提供任何内容情况下,可以指定默认内容。

  • <slot>元素内提供默认内容。

定义默认值插槽组件

<template>
  <h2>使用具名插槽</h2>
  <div>
    <slot name="a"><button>默认按钮</button></slot>
    <slot name="b"></slot>
    <slot name="c"></slot>
  </div>
</template>

使用默认值插槽

<MyMultiSlot>
    <template v-slot:a>

    </template>
    <template v-slot:b>
		<button>按钮二</button>
    </template>
    <template v-slot:c>
		<button>按钮三</button>
    </template>
</MyMultiSlot>

在这里插入图片描述

作用域插槽

在某些场景下插槽的内容可能想要同时使用父组件域内和子组件域内的数据。要做到这一点,我们需要一种方法来让子组件在渲染时将一部分数据提供给插槽。

  • 插槽提供数据。
  • 父组件接收数据。

定义作用域插槽组件:MyListSlot.vue

<script>
export default {
    data() {
        return {
            list: [1, 2, 3],
            message: "你好"
        }
    }
}
</script>
<template>
    <h2>作用域插槽</h2>
    <div>
        <slot :list="list" :message="message"></slot>
    </div>
</template>

使用作用域插槽

需要使用v-slot指令接收props对象。

<script>
import MyListSlot from "../components/MyListSlot.vue"
export default {
    //组件
    components: {
        MyListSlot
    }
}
</script>

<template>
    <!-- 作用域插槽,父组件替换插槽标签,但是数据由子组件提供 -->
    <!-- 无序列表 -->
    <MyListSlot>
        <template v-slot:default="slotProps">
            <p>{{ slotProps.message }}</p>
            <ul>
                <li v-for="item in slotProps.list" :key="item">{{ item }}</li>
            </ul>
        </template>
    </MyListSlot>
    <!-- 有序列表 -->
    <MyListSlot>
        <template v-slot:default="slotProps">
            <ol>
                <li v-for="item in slotProps.list" :key="item">{{ item }}</li>
            </ol>
        </template>
    </MyListSlot>
</template>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值