Skip to content
文章目录

插槽与组件引入

默认插槽

html
<!-- FancyButton.vue -->
<button class="fancy-btn">
  <slot></slot>
  <!-- 插槽出口 -->
</button>
html
<FancyButton>
  <!-- 插槽内容 -->
  Click me!
</FancyButton>

具名插槽

html
<!-- BasicLayout.vue -->
<div class="container">
  <header>
    <slot name="header"></slot>
  </header>
  <main>
    <slot></slot>
  </main>
  <footer>
    <slot name="footer"></slot>
  </footer>
</div>
html
<BaseLayout>
  <template #header>
    <h1>Here might be a page title</h1>
  </template>

  <template #default>
    <p>A paragraph for the main content.</p>
    <p>And another one.</p>
  </template>

  <template #footer>
    <p>Here's some contact info</p>
  </template>
</BaseLayout>

作用域插槽

html
<!-- MyComponent.vue -->
<div>
  <slot :text="greetingMessage" :count="1"></slot>
</div>

默认作用域插槽

html
<MyComponent v-slot="slotProps"> {{ slotProps.text }} {{ slotProps.count }} </MyComponent>

具名作用域插槽

html
<MyComponent>
  <template #header="headerProps"> {{ headerProps }} </template>

  <template #default="defaultProps"> {{ defaultProps }} </template>

  <template #footer="footerProps"> {{ footerProps }} </template>
</MyComponent>

异步组件引入

js
import { defineAsyncComponent } from 'vue'

const AsyncComp = defineAsyncComponent(() => import('./components/MyComponent.vue'))

异步组件全局引入

js
app.component(
  'MyComponent',
  defineAsyncComponent(() => import('./components/MyComponent.vue'))
)

局部引入

html
<script>
  import { defineAsyncComponent } from 'vue'

  export default {
    components: {
      AdminPage: defineAsyncComponent(() => import('./components/AdminPageComponent.vue')),
    },
  }
</script>

<template>
  <AdminPage />
</template>

异步组件加载与错误处理

js
const AsyncComp = defineAsyncComponent({
  // 加载函数
  loader: () => import('./Foo.vue'),

  // 加载异步组件时使用的组件
  loadingComponent: LoadingComponent,
  // 展示加载组件前的延迟时间,默认为 200ms
  delay: 200,

  // 加载失败后展示的组件
  errorComponent: ErrorComponent,
  // 如果提供了一个 timeout 时间限制,并超时了
  // 也会显示这里配置的报错组件,默认值是:Infinity
  timeout: 3000,
})

component is 用法 TS 声明

html
<script setup lang="ts">
import { Component, defineAsyncComponent, ref } from 'vue'
const map = new Map<string, Component>()
map.set(
  'a',
  defineAsyncComponent(() => import('./TsxDemo03.vue'))
)
</script>
<template>
    <component :is="map.get("a")"></component>
</template>

组件内部判断插槽是否被使用

template 中判断

vue
<template v-if="$slots.default">
  <slot> </slot>
</template>
<template v-else>//默认样式</template>

script setup 语法中判断

vue
<template>
  <div>
    <slot />
    <slot name="test" />
  </div>
</template>

<script lang="ts" setup>
import { useSlots } from 'vue'
//判断<slot/>是否有传值
const slotDefault = !!useSlots().default
//判断<slot name="test"/>是否有传值
const slotTest = !!useSlots().test
</script>