LoginSignup
22
10

More than 3 years have passed since last update.

Vuetifyで画面サイズで変わるBreakpointsを使って表示するスタイルや文字数を制限した話

Last updated at Posted at 2020-04-14

画面サイズ毎に表示する文字数制限したい!!

今回Vueitfyを使ってレスポンシブな細かいスタイル調整を行おうと思ったんですが
文字列の長さが不明確で且つ改行ありのデザインだったので少々手こずってしまいました。

Vuetifyでうまくやる方法があるのかも知れませんが、今回はこのような形で解決しました。

結論: $vuetify.breakpointとtruncateを使う

概要

  • $vuetify.breakpointでlgやmdといったブレークポイントを取得
  • $vuetify.breakpointはtemplate上でも使える
  • styleなどに必要な要素を変数に代入(computedで定義すると動的に変わる)
  • truncateメソッドを使って文字切り捨て
  • cssのtext-overflowは改行無しなら使える!(veutifyのclassならtext-truncate

※ templateにはVuetifyを使っているものとします


<template>
  <div>
    <!-- 高さをブレークポイントで動的に変える -->
    <v-card :height="bkPoint.cardHeight">
      <v-card-title>
        {{ title | truncate(bkpoint.titleLength) }}
      </v-card-title>
        <!-- 省略の末尾を指定する -->        
        {{ text | truncate(bkpoint.textLength, '...続き') }}
      </v-card-text>
      <v-card-text>
    </v-card>
  </div>
</template>

<script>
export default {
  filter: {
    /**
    * 文字を切り捨てる [色んな所で使うので共通化するといいよ!]
    * @param {String} text
    * @param {Number} length
    * @param {String} clamp
    */
    truncate (text, length, clamp) {
      text = text || ''
      clamp = clamp || '...'
      length = length || 30

      if (text.length <= length) return text
      return text.substring(0, length) + clamp
    }
  },
  data() {
    return {
       title: 'タイトルは長くても改行なしなら省略する方法が色々ある',
       text: 'テキストは改行ありだとcssだけで対処しきれないのでtrancate関数を作って対応する'
    }
  },
  computed: {
    bkPoint () {
      // $vuetify.breakpointでブレークポイントを取得
      const bkPt = this.$vuetify.breakpoint
      const point = { name: bkPt.name, cardHeight: 200, titleLength: 10, textLength: 15 }
      switch (bkPt.name) {
        case 'xl':
          point.titleLength = 30
          point.textLength = 100
          point.cardHeight = 150
          break
        case 'lg':
          point.titleLength = 20
          point.textLength = 80
          point.cardHeight = 150
          break
        case 'md':
          point.titleLength = 10
          point.textLength = 60
          point.cardHeight = 350
          break
        case 'sm':
          point.titleLength = 10
          point.textLength = 100
          point.cardHeight = 570
          break
        case 'xs':
          point.titleLength = 8
          point.textLength = 100
          point.cardHeight = 600
          break
        default:
          break
      }
      return point
  }
}
</script>

truncateメソッドを共用で定義しよう

こんな感じの処理が書かれたファイルを定義して使いたいところで呼び出してあげよう。

import Vue from 'vue'

/**
 * 文字数を制限して余分があれば省略して末尾...に置換する
 * @param {String} text
 * @param {Number} length
 * @param {String} clamp
 * @returns {String}
 */
Vue.filter('truncate', (text, length, clamp) => {
  text = text || ''
  clamp = clamp || '...'
  length = length || 30

  if (text.length <= length) { return text }
  return text.substring(0, length) + clamp
})

$vuetify.breakpoint

このようにテンプレート内に直接書き込んでコードを書くことを放棄する方法も取れます。

<template>
  <v-dialog :fullscreen="$vuetify.breakpoint.xsOnly">
    ...
  </v-dialog>
</template>

このようにcomputedなどで動的に変動する値として使うこともできます


<script>
export default {
  computed: {
    breakpointName () {
      return this.$vuetify.breakpoint.name // ex: 'lg'
    }
  }
}
</script>
22
10
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
22
10