LoginSignup
1
0

More than 5 years have passed since last update.

初心者がVue.jsの公式ガイドを勉強するメモ コンポーネント編 第二部 スロット関係

Last updated at Posted at 2018-03-06

コンポーネント編 第二部 スロット関係

https://jp.vuejs.org/v2/guide/components.html

スロットによるコンテンツ配信

コンパイルスコープ

  • データをどこに置くべきかの説明ですね。

単一スロット

  • App.vue

<template lang="pug">
  #app
    button(@click="toggle=!toggle") Toggle button
    div
      h1 Parent title
      child-component
        p(v-if="toggle") Parent content
        p(v-if="toggle") Parent content 2

</template>

<script>

import Vue from 'vue'

Vue.component('child-component', {
  template: `<div>
    <h1> Child Title</h1>
    <slot>
      slot content コンポーネントに子要素が無い場合に表示されます。
    </slot>
  </div>`
  })

export default {
  name: 'app',
  data () {
    return {
      toggle: true
    }
  },
  components: {
  }
}
</script>
  • コンポーネントの子要素が無い場合に使われるみたいです。
  • ちなみに、v-show では、子要素が消えないためslotは使われません。

名前付きスロット

  • App.vue
<template lang="pug">
  #app
    app-layout
      h1(slot="header") Header Title
      p main content.
      p main content 2.
      p(slot="footer") Footer

</template>

<script>

import Vue from 'vue'

Vue.component('app-layout', {
  template: `<div class="container">
    <header>
      <slot name="header"></slot>
    </header>
    <main>
      <slot></slot>
    </main>
    <footer>
      <slot name="footer"></slot>
    </footer>
  </div>`
  })

export default {
  name: 'app',
  data () {
    return {
      toggle: true
    }
  },
  components: {
  }
}
</script>
  • 少し味付けしてみます。

<template lang="pug">
  #app
    app-layout
      h1(slot="header") Header Title
      p main content.
      p main content 2.
      p(slot="footer") Footer

</template>

<script>

import Vue from 'vue'

Vue.component('app-layout', {
  template: `<div class="container">
    <header class="header">
      <slot name="header"></slot>
      <h2 class="sub-title"> SubTitle</h2>
    </header>
    <main class="main">
      <slot></slot>
      <p>Main Content 3</p>
    </main>
    <footer class="footer">
      <slot name="footer"></slot>
      <small>  from 2017 to {{ format }} </small>
    </footer>
  </div>`,
    computed: {
      format () {
        const date = new Date();
        const year = date.getFullYear();
        return year
      }
    }
  })

export default {
  name: 'app',
  data () {
    return {
      toggle: true
    }
  },
  components: {
  },
  computed: {
  }
}
</script>
  • スロットに名前をつけて、指定したタグを呼び出していますね。
  • 名無しのslotは、default tag として、個別に呼び出さないものは、この場合mainタグが呼び出されるみたいです。
  • 前回は、子要素の有無でスイッチとしての機能をみましたが、今回は、tagの切り替えとして使っていますね。

スコープ付きスロット

  • App.vue
<template lang="pug">
  #app
    .parent
      child
        template(slot-scope="props")
          span hello from parent
          span {{ props.text }}

</template>

<script>

import Vue from 'vue'

Vue.component('child', {
  template: `<div class="child">
    <slot text="hello from child"></slot>
  </div>`
})

export default {
  name: 'app',
  data () {
    return {
      toggle: true
    }
  },
  components: {
  }
}
</script>
  • propsを引数にして、コンポーネント側のslotのテキストを引っ張ってきています。
  • 作成には、templateにslot-scope属性が必要です。(2.1.0 ~ 2.5.0)

  • App.vue

<template lang="pug">
  #app
    .parent
      my-awesome-list(:items="items")
         li(
          slot="itemSlot"
          slot-scope="props"
          class="my-fancy-item"
         )
          span {{ props.text }}

</template>

<script>

import Vue from 'vue'

Vue.component('my-awesome-list', {
  props: ["items"],
  template: `<ul>
    <slot name="itemSlot" :text="item.name" v-for="item in items"></slot>
  </ul>`
})

export default {
  name: 'app',
  data () {
    return {
      items: [
        { name: 'apple' },
        { name: 'banana' },
        { name: 'Natto' },
      ]
    }
  },
  components: {
  }
}
</script>

  • <template>制限がなくなった見たいです。

分割代入

  • App.vue

<template lang="pug">
  #app
    .parent
      my-awesome-list(:items="items")
         li(
          slot="itemSlot"
          slot-scope="{ text }"
          class="my-fancy-item"
         )
          span {{ text }}

</template>

<script>

import Vue from 'vue'

Vue.component('my-awesome-list', {
  props: ["items"],
  template: `<ul>
    <slot name="itemSlot" :text="item.name" v-for="item in items"></slot>
  </ul>`
})

export default {
  name: 'app',
  data () {
    return {
      items: [
        { name: 'apple' },
        { name: 'banana' },
        { name: 'Natto' },
      ]
    }
  },
  components: {
  }
}
</script>
  • 分割代入は、いろいろなところで、式を簡略化させるのに役立ちますね。

動的コンポーネント

  • 飛ばします。
  • 同じマウントポイントでの切り替え機能みたいです。

  • その他が残っていますが、スロット関係の大枠がほぼ把握できたので、ここで一旦終了します。

  • その他編は、コンポーネントの理解を深めてからで良さそうな内容なので、後回しになる思います。

  • 状態管理などが気になるので、そちらに行くと思います。(笑)

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0