Help us understand the problem. What is going on with this article?

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

More than 1 year has 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プラグインがあると便利だよねという話が出たので勉強のためにも是非作ってみたいと思いました。

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.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  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
ユーザーは見つかりませんでした