コラム

[Vue.js]Vue.jsでDOMやコンポーネントを操作するのに便利なref機能

ExcelライクのアプリをVue.jsで作成していて便利な機能だなと思ったので紹介します。
DOMやコンポーネントにアクセスし操作が出来るテンプレート参照という機能を使います。
これはタグ内に「ref」という属性を使用します。
以下、実際に使用例をコードで行きます。

使用例1 最も単純なアクセス

divへの操作を行う最も単純な例です。

<template>
  <div id="app">
    <div ref='reftest'>
		Refテストです。
    </div>
    <input type="button" @click="changeColor" value="色チェンジ">
  </div>
</template>

<script>

export default {
  name: 'App',
  methods:{
    changeColor(){
		   this.$refs.reftest.style.background = '#0FF'
       //this.$refs['reftest'].style.background = '#0FF'
    }
  }
}
</script>

<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
div{
	width:200px;
	height:20px;
	background:#0F0
}
</style>

divに「ref='reftest'」という属性を付けています。「reftest」部分は任意の名前を使用できます。
これを指定するとメソッドなどで、このdivの操作する事が出来ます。
例では背景色を変えていますが、divへは「this.$refs.reftest」又は「this.$refs['reftest']」によってする
アクセスする事が可能です。

使用例2 コンポーネントへのアクセス

「Parent」と「Child」という2つのコンポーネントを用意し、「Panret」が「Child」のメソッドを呼ぶ例です。

<template>
	<div>
		{{viewMsg}}
	</div>
</template>

<script>
export default {
	name: 'Child',
	props: {
		msg: String
	},
	data(){
		return {
			viewMsg : ''
		}
	},
	mounted(){
		this.viewMsg = this.msg
	},
	methods:{
		setText:function( value ){
			this.viewMsg = value
		}
	}
}
</script>

propsで渡されたメッセージを表示します。
「setText」メソッドは表示するメッセージを変更するメソッドで「Parent.vue」から呼ばれます。

<template>
	<div>
		<Child msg='コンポーネントテスト' ref="cmptest" />
		<br/>
		<input type="button" @click='clickCmp' value="コンポーネント"><br/>
	</div>
</template>

<script>
import Child from './Child.vue'

export default {
	name: 'Parent',
	components: {
		Child
	},
	methods:{
		clickCmp(){
			this.$refs.cmptest.setText("コンポーネントテスト click")
		}
	}
}
</script>

Childタグにref属性を付けています。
ボタンが押下されたら、「this.$refs.cmptest..setText("コンポーネントテスト click")」でChildコンポーネントの
メソッドを呼んでいます。

使用例3 v-forを使用して同一名称で複数使用する例

v-forにより複数のChildコンポーネントを作成し、ref名にも同一名称を使用する例です。
「Child」コンポーネントは同じです。
これが使い勝手が良いので多用しています。

<template>
	<div>
		<center>
		<table>
			<tr v-for="(data) in list" :key="data">
				<td><Child :msg='data' ref='child'/></td>
			</tr>
		</table><br/>
		<input type="button" @click='click0' value="0">
		<input type="button" @click='click1' value="1">
		<input type="button" @click='click2' value="2"><br/>
		<input type="button" @click='clickAll' value="all">
		</center>
	</div>
</template>

<script>
import Child from './Child.vue'

export default {
	name: 'Parent',
	components: {
		Child
	},
	data(){
		return {
			list :[]
		}
	},
	created(){
		this.list =  ['0', '1', '2']
	},
	methods:{
		click0(){
			this.$refs.child[0].setText("0 click")
		},
		click1(){
			this.$refs.child[1].setText("1 click")
		},
		click2(){
			this.$refs.child[2].setText("2 click")
		},
		clickAll(){
			let i = 0
			this.$refs.child.forEach((value) => {
				value.setText(i + " click")
				i++
			})
		}
	}
}
</script>

・要素が3つ入っている配列を用意します。
・その配列をv-forでループさせ、「Child」コンポーネントを作成しています。渡すメッセージは配列の値です。
・refの名称は全てchildという名称にしています。
・0、1、2、allというボタンを用意し、それぞれメソッドと関連付けます。
・メソッドは1番目のChildへの操作のclick0、2番目のChildへの操作のclick1、3番目のChildへの操作のclick2、全ての
Childへの操作のclickAllを用意しています。

実行イメージ

以上、私が良く使うRefの使用方法を説明しました。参考になれば幸いです。

この記事をシェアする
  • Facebookアイコン
  • Twitterアイコン
  • LINEアイコン

お問い合わせ ITに関するお悩み不安が少しでもありましたら、
ぜひお気軽にお問い合わせください

お客様のお悩みや不安、課題などを丁寧に、そして誠実にお伺いいたします。

お問い合わせはこちら
お電話でのお問い合わせ 03-5820-1777(平日10:00〜18:00)
よくあるご質問