Vue.js - Study Note 2

Views: 1032
Wrote on April 14, 2020, 2:39 a.m.

Slot

Unnamed slot or the default slot. Vue slot follows the rule of the Web Components Proposals, only one unnamed slot is allowed in individual component. Slot can be seen as the placeholder to reserve a spot for the content passed from parent component. The default text of “Sorry, this menu is unavailable” will show up when parent component pass nothing, but if there is data passing in, the default text will be overridden by it (Menu1, Menu2 .. etc).

<div id="app">
  <global-component>Menu1</global-component>
  <global-component>Menu2</global-component>
  <global-component>Menu3</global-component>
  <global-component>Menu4</global-component>
  <global-component></global-component>
</div>
  Vue.component("global-component", {
    template: `
      <div>
          <slot>Sorry, this menu is unavailable</slot>
      </div>
   `
  })
  new Vue({
    el: '#app',
    data() {
      return {}
    },
  })

Result:

Menu1
Menu2
Menu3
Menu4
Sorry, this menu is unavailable

Named Slot

Only one unnamed slot is allowed as mentioned above, so if you need to have multiple slots in one component, named slot is needed. To define a named slot, simply insert the code into a <template> tag with a v-slot: directive then assign a name for it.

<div id="app">
  <global-component>
      <template v-slot:namedSlot> Title </template>
      <br>
      Menu
  </global-component>
</div>
  Vue.component("global-component", {
    template: `
       <div>
        <slot name="namedSlot"> Named Slot </slot>
        <slot>Sorry, this menu is unavailable</slot>
      </div>
   `
  });

  new Vue({
    el: '#app',
    data() {
      return {}
    },
  })

Result:

Named Slot
Menu

Scoped Slots

You can pass either data or functions with slots, scoped slot does the job! Example below explains everything about it.

<div id="app">
  <global-component>
    <template v-slot:default="slotProps">{{ slotProps.msg.part1 }}</template>
  </global-component>
</div>
  Vue.component("global-component", {
    data() {
      return {
        msg: {"part1": "Nihao!", "part2": "Zaijian~"}
      }
    },
    template: `
       <div>
        <slot v-bind:msg="msg">
          {{ msg }}
        </slot>
      </div>
   `
  });

  new Vue({
    el: '#app',
    data() {
      return {}
    },
  })

Result:

Nihao