VueJS 速習チュートリアル

Vue テンプレート参照 (Template Refs)

Vue のテンプレート参照(Template Refs)は、特定の DOM 要素を参照するために使用されます。
HTML タグに ref 属性をセットすると、生成された DOM 要素が $refs オブジェクトに追加されます。
これは、生の JavaScript における getElementById()querySelector() といったメソッドに代わる、Vue における推奨のアプローチです。

1. 'ref' 属性と '$refs' オブジェクト

ref 属性が付与された HTML タグは $refs オブジェクトに追加され、後で <script> タグの中からアクセスできるようになります。

1.1 実装例

以下の例では、<p> 要素内のテキストを変更しています。

App.vue:

<template>
  <h1>実装例</h1>
  <p>ボタンをクリックして、緑色の p 要素のテキストを "Hello!" に変更します。</p>
  <button @click="changeVal">テキストを変更</button>
  <p ref="pEl">これは初期テキストです</p>
</template>

<script>
  export default {
    methods: {
      changeVal() {
        // ref="pEl" を指定した要素にアクセス
        this.$refs.pEl.innerHTML = "Hello!";
      }
    }
  }
</script>

次の例では、$refs オブジェクトを使用して、あるタグの値を別のタグにコピーする方法を示します。

1.2 テキストのコピー実装例

最初の <p> タグのテキストを 2 番目の <p> タグにコピーします。

App.vue:

<template>
  <h1>実装例</h1>
  <p ref="p1">ボタンをクリックして、このテキストを下の段落にコピーします。</p>
  <button @click="transferText">テキストを転送</button>
  <p ref="p2">...</p>
</template>

<script>
  export default {
    methods: {
      transferText() { 
        // p1 から p2 へ内容をコピー
        this.$refs.p2.innerHTML = this.$refs.p1.innerHTML;
      }
    }
  };
</script>

2. '$refs' から入力値を取得する

$refs オブジェクトに追加された HTML 要素のさらに深いプロパティ(value など)にもアクセス可能です。

2.1 実装例

入力フィールド(input)に書き込まれた内容を、そのまま <p> 要素に反映させます。

App.vue:

<template>
  <h1>実装例</h1>
  <p>入力フィールドに文字を入力すると、'$refs' オブジェクトを通じてテキストが最後の段落にコピーされます。</p>
  <input ref="inputEl" @input="getRefs" placeholder="何か入力してください..">
  <p ref="pEl"></p>
</template>

<script>
  export default {
    methods: {
      getRefs() { 
        // input 要素の value を p 要素の innerHTML に代入
        this.$refs.pEl.innerHTML = this.$refs.inputEl.value;
      }
    }
  };
</script>

3. v-for と 'ref' の併用

v-for を使用して動的に生成される HTML 要素に ref 属性を付けた場合、それらは $refs オブジェクト内に配列(Array)として格納されます。

3.1 実装例

ボタンをクリックすると、$refs オブジェクト内に配列として保存されている「3 番目」のリスト要素の内容を表示します。

App.vue:

<template>
  <h1>実装例</h1>
  <p>ボタンをクリックして、$refs オブジェクトに配列として格納されている 3 番目のリスト要素を表示します。</p>
  <button @click="getValue">3 番目のリスト要素を取得</button><br>
  <ul>
    <li v-for="x in liTexts" ref="liEl">{{ x }}</li>
  </ul>
  <pre>{{ thirdEl }}</pre>
</template>

<script>
  export default {
    data() {
      return {
        thirdEl: ' ',
        liTexts: ['リンゴ', 'バナナ', 'キウイ', 'トマト', 'ライチ']
      }
    },
    methods: {
      getValue() { 
        // 配列のインデックス 2(3番目)にアクセス
        this.thirdEl = this.$refs.liEl[2].innerHTML;
        console.log("this.$refs.liEl = ", this.$refs.liEl);
      }
    }
  };
</script>

<style>
pre {
  background-color: lightgreen;
  display: inline-block;
  padding: 5px;
}
</style>