Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
17
Help us understand the problem. What is going on with this article?
@sunecosuri

パンくずコンポーネントと範囲選択するコンポーネントについて

More than 3 years have passed since last update.

本当は vue-test-loader× jest の記事について書きたかったのですが間に合いませんでしたので、最近自分で作って地味に便利だと感じたSFC(単一ファイルコンポーネント)の紹介をしたいと思います。:bow:

クリック時に範囲選択するコンポーネント

最近ではコピーボタンが主流ですが、個人的にはぱっと見て気づかないことが多く直感的じゃないと思う時があります。
そのためついつい直接対象をドラッグしてコピーしがちです。
以下のようにコンポーネントを定義し、対象をクリックするだけでコンポーネントで囲った範囲を直接選択できるようにしコピーしやすいコンポーネントを作成しました。
やっていることはクリックイベント時にDOMレンジを使って対象範囲を選択するシンプルなものです。

demo TodoListのタスクをクリックすると選択します。

  1. 範囲選択するコンポーネントを定義(今回はLineSelector.vue と定義しています)
// LineSelector.vue
<template>
  <span @click="clickedSelect" ref="selectText">
  <slot />
  </span>
</template>

<script>
export default {
    methods: {
        clickedSelect () {
      const range = document.createRange()
      range.selectNodeContents(this.$refs.selectText)
      const selection = window.getSelection()
      selection.removeAllRanges()
      selection.addRange(range)
        }
    }
}
</script>
  1. 定義したコンポーネントを読み込み、選択範囲を<line-selector>で囲みます。
    以下のコードではTodoList のtextをコピーできるようにしております。
<template>
  <li>
    <line-selector>{{ todo.text }}</line-selector>
    <button @click="$emit('remove', todo.id)">
      X
    </button>
  </li>
</template>

<script>
import LineSelector from './LineSelector.vue'

export default {
    components: {
        LineSelector
    },
  props: {
    todo: {
      type: Object,
      required: true
    }
  }
}
</script>

パンくずコンポーネント

vueでパンくずを用いる場合、既にvue-breadcrumbsといったpluginが既にあるのですがより柔軟に対応する必要があったため、以下のようにコンポーネントを作成しました。

  1. パンくずコンポーネントを定義
// Breadcrumb.vue
<template>
  <ul :class="$style.list">
    <li :class="$style.item" v-for="(crumb, key) in breadcrumbs" :key="name">
      <span v-if="crumb.path"><nuxt-link :to="crumb.path" >{{ crumb.name }}</nuxt-link></span>
      <span v-else>{{ crumb.name }}</span>
    </li>
  </ul>
</template>

<script>
export default {
  props: {
    breadcrumbs: {
      type: Array
    }
  }
}
</script>

<style>
.list {
  list-style: none;
  text-align: left;
  margin: 0;
}
.item {
  display: inline-block;
}
.item::after {
  content: '>';
  display: inline-block;
}
.item:last-child::after {
  content: none;
}
</style>

  1. 定義したコンポーネントを読み込み、pathと表示名を持ったオブジェクトをpropsで渡すとパンくずリストが表示されます。以下の場合だとほげ > ふが といった表示をします
<breadcrumb :breadcrumbs="breadcrumbs" />
<script>
import Breadcrumb from './Breadcrumb.vue'

export default {
  components: {
    Breadcrumb,
  },
  data: function () {
    return {
      breadcrumbs: [
        {
          name: 'ほげ',
          path: '/hoge'
        },
        {
          name: 'ふが'
        }
      ]
    }
  },

}
</script>

まとめ

Vue.jsに触れて半年くらいになりますが、SFCは柔軟すぎると思えるくらいとても便利です。
今後はvue-i18nと連携してブロックで定義したものをそのままパンくずとして表示して使えるようにした
Nuxt,Vueプラグインがあると便利だよねという話が出たので勉強のためにも是非作ってみたいと思いました。

17
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
17
Help us understand the problem. What is going on with this article?