Vue.jsで改行が適用されないときの対処法(文字列の改行)|white-spaceの使い方を実例で解説

vue-js-prograshi(プロぐらし)-kv Vue.js
記事内に広告が含まれていることがあります。

Vue.jsのテンプレート内で改行を含んだ文字列を{{ }}マスタッシュ構文で表示すると、デフォルトの状態では改行されずに表示されてしまいます。

ここでは、改行を含んだ文字列を改行する方法について解説しています。


改行できない例

次のようにdataでmessageを定義し、その値に改行したテキストを指定します。

これをテンプレートの中で呼び出すとブラウザ上は改行が空白になってしまいます。

<!DOCTYPE html>
<html>
  <head>
    <title>New Line</title>
    <script src="https://unpkg.com/vue"></script>
  </head>
  <body>
    <div id="app">
        {{message}}
    </div>

    <script>
      new Vue({
        el: "#app",
        data: {
          message: `改行を含んだテキストを
                    表示させる方法について
                    解説しています。   
                    半角スペース10個「        」    
                    がどう表示されるか        `
        }
      });
    </script>
    
    <style lang=scss scoped>
    </style>
  </body>
</html>


左側がコード、右側がブラウザ上の表示です。


改行する方法

改行する方法は2つあります。

  1. CSSで改行する
  2. メソッドを使って変換する


CSSで改行する

1つ目はCSSで改行する方法です。

CSSで改行を変換するには、対象のタグにwhite-space: pre-line;を適用します。

white-space: pre-line;


ブラウザで確認すると改行が反映されています。


white-spaceとは?

ホワイトスペースとは、ソースコードの中では空白や改行として扱われるものの、ブラウザに表示した時に、画面に反映されない文字のことです。

半角スペース、タブ、改行などの制御文字が該当します。(全角スペースはホワイトスペースではなく、1つの文字として認識されます。)

この、ホワイトスペースのレイアウトを指定するのがwhite-spaceプロパティです。

ソースコード中のホワイトスペースをどう扱うかによって、whites-spaceプロパティの値を指定します。

内容
normal1行で表示。折り返しあり
nowrap1行で表示。折り返しなし
pre改行文字と<br>のみ折り返しに変換。
折り返しなし。
pre-wrap改行文字と<br>のみ折り返しに変換。
折り返しあり。
pre-line改行文字と<br>を折り返しに変換。
複数のホワイトスペースを1つにまとめる。
折り返しあり。
break-spacespre-wrapと同じですが、行末の空白を必要に応じて折り返します。
改行空白とタブ折り返し
normalしないまとめるあり除去
nowrapしないまとめるなし(1行)除去
preするそのままなしそのまま
pre-wrapするそのままありぶら下げ
pre-lineするまとめるあり除去
break-spacesするそのままあり折り返す
https://developer.mozilla.org/ja/docs/Web/CSS/white-space


確認用のコード

各値を確認するためのコードとして以下を使用します。

<!DOCTYPE html>
<html>
  <head>
    <title>New Line</title>
    <script src="https://unpkg.com/vue"></script>
  </head>
  <body>
    <div id="app">
      <div class="msg-wrapper">
        <p>{{message}}</p>
      </div>
    </div>

    <script>
      new Vue({
        el: "#app",
        data: {
          message: `改行を含んだテキストを          
                    表示させる方法について       
                    解説しています。                          
                    半角スペース10個「        」がどう表示されるか        `
        }
      });
    </script>
    
    <style lang=scss scoped>
      .msg-wrapper p{
        /* white-space: normal; */
        /* white-space: nowrap; */
        /* white-space: pre; */
        /* white-space: pre-wrap; */
        /* white-space: pre-line; */
        white-space: break-spaces;
      }
      
      .msg-wrapper{
        padding: 10px;
        width: 300px;
        border: 1px dashed gray
      }
    </style>
  </body>
</html>

messageの2,3行の末尾には複数の半角スペースを入れています。(pre-wrapとbreak-spacesの比較用)


white-spaceプロパティを適用していないときは以下のようになります。

改行されずに1行が、親要素の端で折り返します。



normal

1行で表示します。親の要素の幅に合わせて折り返します。

詳細

連続するホワイトスペースはまとめ、ソース内の改行文字もホワイトスペースとして扱います。行ボックスを埋めるために、必要なら行を折り返します。

実例

表示は、white-spaceプロパティを指定していないときと同じです。


nowrap

1行で表示します。親要素の幅があっても折り返ししません。 (はみ出します)

詳細

連続するホワイトスペースはまとめ、ソース内の改行文字もホワイトスペースとして扱います。行を折り返しません。

normal と同じくホワイトスペースを詰めますが、行の折り返しは行いません。)

実例


pre

改行文字と<br>のみ折り返しに変換します。親要素に合わせた折り返しはしません。(はみ出します)

詳細

連続するホワイトスペースはそのまま残され、行の折り返しは、ソース内の改行文字と、<br>
要素でのみ行います。

実例


pre-wrap

改行文字と<br>のみ折り返しに変換します。親要素に合わせて折り返します。

詳細

連続す連続するホワイトスペースはそのまま残されます。行の折り返しは、改行文字や<br>
要素のあるときか、行ボックスを埋めるのに必要なときに行います。

実例


pre-line

改行文字と<br>のみ折り返しに変換します。複数のホワイトスペースを1つにまとめます。親要素に合わせて折り返します。

詳細

連続するホワイトスペースは詰められて 1 つになります。行の折り返しは、改行文字や<br>
要素のあるときか、行ボックスを埋めるのに必要なときに行われます。

実例


break-spaces

改行 pre-wrapと同じですが、行末の空白を必要に応じて折り返します。

詳細

下記の点を除いて、動作は pre-wrap と同じです。

  • そのまま残された連続するホワイトスペースは、行末にあるものを含め、空間を占有します。
  • 残されたそれぞれのホワイトスペースの後で、ホワイトスペースの間を含め、改行する可能性があります。
  • そのような残された空白は空間を占有し、ぶら下がらず、ボックスの固有の寸法に (min-content size および max-content size に) 影響します。

実例


メソッドを使って変換する

メソッドを使って改行を含んだテキストとして表示する方法もあります。

実装の流れは以下になります。

  1. テキストを引数として改行コードを<br>タグに変換する
  2. v-htmlでバインドしてテンプレート内に表示する
注意点

v-htmlでHTMLをそのまま出力するため、このメソッドを適用するのは信頼できるテキストのみにする必要があります。

ユーザーが入力できるHTMLに対してこの方法を使うと、クロスサイトスクリプティング(XSS)のリスクがあります。


コード例

<!DOCTYPE html>
<html>
  <head>
    <title>New Line</title>
    <script src="https://unpkg.com/vue"></script>
  </head>
  <body>
    <div id="app">
      <p v-html="htmlText(message)"></p>
    </div>

    <script>
      new Vue({
        el: "#app",
        data: {
          message: `改行を含んだテキストを
                    表示させる方法について
                    解説しています。`
        },
        methods:{
          htmlText(msg){
            if( !!(msg) ){
              return msg.replace(/\r?\n/g, '<br>')
            }
          }
        }
      });
    </script>
    
  </body>
</html>


ブラウザで確認すると、テキストが改行されて表示されます。


テキストを引数としてメソッドを作成する

ソースコードの改行コードを<br>に変換するメソッドを作成します。

        methods:{
          htmlText(msg){
            if( !!(msg) ){
              return msg.replace(/\r?\n/g, '<br>')
            }
          }
        }

ifでテキストの存在確認をし、存在する場合はreplaceメソッドを使って変換を行います。

処理内容は改行コードを<br>タグに変換しています。


replaceメソッド

replaceメソッドは第1引数に正規表現でパターンを記述し、第2引数に変換する文字列を記述します。

replace(regexp, newSubstr)

(参考)MDN String.prototype.replace()


/\r?\n/g

/\r?\n/gは文字列の改行を指定する正規表現です。

正規表現のパターンは/ /の中に記述します。

改行コードはMacとWindowsなどのOSによって異なります。現在考慮すべき全パターンは2つで、\n, \r\nです。

▼改行コードの詳細

パターンコード内容主なOS正式名称
LF\nカーソルを新しい行に移動する(行を追加する)Linux系(Mac OS X以降)Line Feed
CR\rカーソルを左端の位置に戻す(復帰の意味)昔のMacOS(v9以前)Carriage Return
CRLF\r\n左端にカーソルを戻して改行するWindows(CR + LF)

\rは2文字で1つの意味を表すメタ文字です。後ろの?は直前のパターンの0~1回の繰り返しです。

つまり、\r?は、何もなしか、\rの2つにマッチします。

その後ろに、\nがあるので、/\r?\n/の正規表現は、\n, \r\nにマッチします。

一番後ろのgはオプションで該当するすべての文字列を置換対象にします。gオプションがないと、一番最初にマッチした文字列しか置換されません。

正規表現のオプション(フラグ)

/gのように、正規表現のパターンの適用範囲を指定するオプションが用意されています。

オプション(フラグ)内容
gマッチしたすべての文字列を対象とする。
(グローバル検索)
i大文字・小文字を区別しない
d一致した部分文字列の位置を生成
m複数行の検索
s. を改行文字と一致するようにする
u“unicode” 。パターンを一連の Unicode コードポイントとして扱う
y対象文字列の現在の位置から始まる部分に一致するものを探す。(「先頭固定」 (sticky) 検索)

(参考)MDN 正規表現 フラグを用いた高度な検索


v-htmlでバインドしてテンプレート内に表示する

最後に変換したテキストをテンプレート内にHTMLとして表示します。

HTMLとして表示するには、v-htmlディレクティブを使います。

<タグ v-html="変数 or メソッド or 文字列"></タグ>

次のようにすれば、htmlTextメソッドに変数messageを引数として渡し、その実行結果をHTMLとしてpタグの中に表示します。

<p v-html="htmlText(message)"></p>
注意点

XSS 脆弱性を容易に引き起こすので、ウェブサイトで動的に任意のHTMLを描画することは、非常に危険です。信頼できるコンテンツにだけ HTML 展開を利用してください。ユーザーから提供されたコンテンツに対しては決して使用してはいけません。

(参考)Vue.js v-htmlディレクティブ


(参考)v-text

v-htmlは文字列をHTML(innerHTML)として出力するものですが、v-textを使えばプレーンテキストとして出力することができます。

上記例のv-htmlをv-textに返るとreplaceメソッドで置換後の内容が確認できます。


Vue.jsにおける便利なディレクティブは他にもあります。

(参考)Vue.js API ディレクティブ一覧

タイトルとURLをコピーしました