Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

This article is a Private article. Only a writer and users who know the URL can access it.
Please change open range to public in publish setting if you want to share this article with other users.

vue入門03(テンプレート構文)

Last updated at Posted at 2024-05-28

概要

  • v-onceディレクティブ
  • v-preディレクティブ
  • v-htmlディレクティブ
  • v-cloakディレクティブ
  • v-textディレクティブ
  • Javascript式
  • v-bindの省略記法

様々なテンプレート制御ディレクティブを使う

  • ディレクティブはプログラミングにおける「指示」を指す

色んな例

  • v-once
    →初回だけバインディング
  • v-pre
    →要素とすべての子要素のコンパイルをスキップ
  • v-html
    →プレーンなHTMLを挿入
  • v-cloak
    →インスタンスの準備が終わると取り除かれる
  • v-text
    →マスタッシュ構文の代わりに

v-onceディレクティブ

  • 初回だけテンプレートを評価し、それ以降は静的なコンテンツとして扱いたい
  • つまり初回だけテキストバインディングを行いたい
    v-onceディレクティブを利用
例えば…
  • API呼び出しなどを画面がロードされた時に行いたいが、それ以降結果は変わらないので最初の1回だけで良い、などの状況
  • ページ更新のパフォーマンス向上

実際のコード

いったんボタンを押すとテキストが反転する処理を実装

<div id="app">
  <p>{{ message }}</p>
  <button v-on:click="clickHandler">
    Click!
  </button>
</div>
const app = Vue.createApp({
  data: () => ({
    message: 'Hello Vue.js!'
  }),
  methods:{
    clickHandler: function(event){
      this.message = this.message.split('').reverse().join('')
    }
  }
})
app.mount('#app')

スクリーンショット 2024-05-28 230821.png
スクリーンショット 2024-05-28 230827.png

  • ボタンを押すとテキストが反転
  • this.message.split('').reverse().join('')
    →反転する処理は素のjavascriptで書いている
  • split('')で各文字を分離して、それを配列に変換
  • reverse()では配列を受けとり、その要素を逆にする
  • join('')はその配列を受け取り、その中の要素を逆にする
  • 文字列を反転するにはこの流れなんだな、くらいの理解でよい

p要素にv-onceディレクティブを設定する

<div id="app">
  <p v-once>{{ message }}</p>
  <button v-on:click="clickHandler">
    Click!
  </button>
</div>

スクリーンショット 2024-05-28 230821.png

  • pタグにv-onceを設定
  • ページは通常通り表示される
  • ボタンを押しても文字は反転しない
  • クリックをしてもデータバインディングが行われない
  • v-onceディレクティブは初回だけテンプレートを評価して、それ以降は静的なコンテンツとして扱うため
  • 処理を減らして描画更新のパフォーマンスを上げたい時に利用できる

v-preディレクティブ

  • 要素とすべての子要素のコンパイルをスキップしたい
    →v-preディレクティブを使用

例など

  • 生のマスタッシュ タグを表示したいとき
  • ディレクティブのない大量のノードをスキップすることで、コンパイルのスピードを上げる
<div id="app">
  <p v-pre>{{ message }}</p>
</div>
const app = Vue.createApp({
  data: () => ({
    message: 'Hello Vue,js!'
  })
})
app.mount('#app')

スクリーンショット 2024-05-28 232307.png

  • ↑↑↑通常であればこのように表示される

スクリーンショット 2024-05-28 232318.png
↑↑↑v-preディレクティブを追加するとこのようにマスタッシュ構文をそのまま表示できる

v-htmlディレクティブ

  • プレーンなHTMLを挿入したい
    →v-htmlを使用
  • 指定した要素のinnerHTMLを更新できる
前提
  • マスタッシュタグを使った描画ではクロスサイトスクリプティング対策としてデータオブジェクトにHTMLを入れてもHTMLとは評価されず、タグがテキストとして表示される。
  • クロスサイトスクリプティング
    →脆弱性のあるウェブサイトにユーザーを誘導することによりユーザー環境で不正スクリプトを実行させることができてしまうもの

通常の状態

<div id="app">
  <p>{{ message }}</p>
</div>
const app = Vue.createApp({
  data: () => ({
    message: 'Hello <span style="color:red;">Vue,js!</span>'
  })
})
app.mount('#app')

スクリーンショット 2024-05-29 205231.png

  • js側にspanタグでスタイル指定したがそのままテキストで表示されている

v-htmlを使用

<div id="app">
  <p>{{ message }}</p>
  <p v-html="message"></p>
</div>
const app = Vue.createApp({
  data: () => ({
    message: 'Hello <span style="color:red;">Vue,js!</span>'
  })
})
app.mount('#app')

スクリーンショット 2024-05-29 210050.png

  • v-htmlを使用した箇所は色が変更されて表示されている
  • v-htmlは主にサーバーサイドから取得したHTMLを表示するときに使う

注意点

  • クロスサイトスクリプティング脆弱性を引き起こす可能性あり、慎重に使用する
  • v-htmlディレクティブで使用するデータやテンプレートは信頼できるデータのみ使用する
  • サービスを利用するユーザーが入力したコンテンツには絶対使用しない

v-cloakディレクティブ

  • cloak→覆い隠すという意味
  • ページを表示開始してから、インスタンスの作成が終わるまでの間に、マスタッシュタグなど、コンパイル前のテンプレートが表示されてしまうのを防ぎたい
  • ページを更新したときなどに一瞬コンパイル前のマスタッシュ構文の状態がページにチラ見えしてしまう状態
<div id="app">
  <p v-cloak>{{ message }}</p>
</div>
const app = Vue.createApp({
  data: () => ({
    message: 'Hello Vue,js!'
  })
})
app.mount('#app')
[v-cloak]{
    display: none;
}
  • index.html側にはv-clockを指定
  • cssでv-cloakを非表示にする
  • こちらでちらつきはなくなる

v-textディレクティブ

  • マスタッシュの代わりに、ディレクティブを使いたい
    →v-textディレクティブを使用

通常

<div id="app">
  <h2>Mustache</h2>
  <p>{{ message }}</p>
</div>
const app = Vue.createApp({
  data: () => ({
    message: 'Hello Vue,js!'
  })
})
app.mount('#app')

スクリーンショット 2024-05-29 212646.png

v-textを利用して同じ状態を再現する

<div id="app">
  <h2>Mustache</h2>
  <p>{{ message }}</p>
  <h2>v-text</h2>
  <p v-text="message"></p>
</div>
const app = Vue.createApp({
  data: () => ({
    message: 'Hello Vue,js!'
  })
})
app.mount('#app')

スクリーンショット 2024-05-29 213013.png

  • マスタッシュ構文と、v-textディレクティブで記述した内容が同じ表示状態

マスタッシュ構文とv-textディレクティブどちらを使うべき?

  • 基本的にはどちらでもOK
  • マスタッシュ構文に統一するのがおすすめ
  • v-textディレクティブでは、配下のテキストをまるごと置き換えるため、テキストの一部を書き換えたい場合はマスタッシュ構文を利用する必要があるため

Javascript式を使う

  • これまでのテンプレート内では単純なプロパティキーだけしようしていた
    {{ message }}

Vue.jsではデータバインディング内部でJavascript式を利用することができる

{{ number + 1 }}

<div id="app">
  <p>{{ message }}</p>
  <p>{{ number + 1 }}</p>
  <p>{{ message.split('').reverse().join('') }}</p>
  <p>{{ ok ? 'YES' : 'NO' }}</p>
</div>
const app = Vue.createApp({
  data: () => ({
    message: 'Hello Vue,js!',
    number: 100,
    ok: true
  })
})
app.mount('#app')

スクリーンショット 2024-05-29 214426.png

注意点

  • 各バインディング式は単一式のみを含むことができる
  • 下記はエラーとなる
<p>{{ let x = 1 }}</p>
<p>{{ if(ok){return message} }}</p>
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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?