xgqfrms™, xgqfrms® : xgqfrms's offical website of cnblogs! xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!

Vue 3 slot All In One

Vue 3 slot All In One

API

https://vuejs.org/guide/components/slots.html

template 用作 slot 的最外层容器 ⚠️

vue slot alias

v-slot:default


<Suspense>
  <!-- default slot -->
 <Dashboard v-slot:default/>

  <!-- fallback slot -->
  <template v-slot:fallback>
    Loading...
  </template>
</Suspense>

alias 简写 #default

<Suspense>
  <!-- default slot -->
 <Dashboard #default/>

  <!-- fallback slot -->
  <template #fallback>
    Loading...
  </template>
</Suspense>

Dynamic Slot Names

<base-layout>
  <template v-slot:[dynamicSlotName]>
    ...
  </template>

  <!-- with shorthand -->
  <template #[dynamicSlotName]>
    ...
  </template>
</base-layout>

https://vuejs.org/guide/essentials/template-syntax.html#directives

Render Scope

Slot content has access to the data scope of the parent component, because it is defined in the parent. ✅

Slot content does not have access to the child component's data.

everything in the parent template is compiled in parent scope;
everything in the child template is compiled in the child scope;

Scoped Slots

<!-- parent component -->
<template>
<ChildComponent v-slot="slotProps">
  {{ slotProps.text }}
  {{ slotProps.count }}
</ChildComponent>
</template>

对象解构

<!-- parent component -->
<template>
<ChildComponent v-slot="{ text, count }">
  {{ text }}
  {{ count }}
</ChildComponent>
</template>

<!-- child component -->
<template>
<div>
  <slot :text="greetingMessage" :count="1"></slot>
</div>
</template>

<ChildComponent>
  <template #header="headerProps">
    {{ headerProps }}
  </template>

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

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

  <ScopedSlot>
    <template #header="headerProps">
      {{ headerProps }}
      <br />
      {{ headerProps.hello + "✅" + headerProps.world }}
    </template>

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

    <!-- <template #footer="footerProps">
      {{ footerProps }}
    </template> -->
    <template #footer="{ a, b }">
      a = {{ a }}
      <br />
      b = {{ b }}
    </template>
  </ScopedSlot>

<template>
  <slot name="header" hello="hello" world="world"></slot>
  <slot abc="hello" xyz="world"></slot>
  <slot name="footer" a="hello" b="world"></slot>
</template>

Renderless Component

<script>
export default {
  data() {
    return {
      x: 0,
      y: 0
    }
  },
  methods: {
    update(e) {
      this.x = e.pageX
      this.y = e.pageY
    }
  },
  mounted() {
    window.addEventListener('mousemove', this.update)
  },
  unmounted() {
    window.removeEventListener('mousemove', this.update)
  }
}
</script>

<template>
  <slot :x="x" :y="y"/>
</template>

<template>
	<MouseTracker v-slot="{ x, y }">
  	Mouse is at: {{ x }}, {{ y }}
	</MouseTracker>
</template>

demo

https://codesandbox.io/s/infallible-meadow-41pm3s?file=/src/App.vue

refs

vue slot All In One

https://www.cnblogs.com/xgqfrms/p/14494417.html



©xgqfrms 2012-2020

www.cnblogs.com/xgqfrms 发布文章使用:只允许注册用户才可以访问!

原创文章,版权所有©️xgqfrms, 禁止转载 🈲️,侵权必究⚠️!


posted @ 2022-05-29 23:29  xgqfrms  阅读(50)  评论(2编辑  收藏  举报