画面サイズ毎に表示する文字数制限したい!!
今回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>