2020年7月21日 星期二

[Vue.js] $ref 和 directive 操作 DOM 的兩種方式及範例

以下整理 Vue 兩種操作 DOM 的方法。程式碼內容是根據輸入的數字來決定 div 的高度,這些範例僅是方便了解使用的方式,不代表這類的需求適合使用。

一、自訂索引名 ($refs)
自訂索引名有點像是 id 一樣,假設在元件上設定 ref myBlock,就可以用 this.$refs.myBlock 取得 DOM 元素。
<template>
	<input
		v-model.number="heightModel"
		type="number">
	<div
		ref="myBlock"
		class="border border-danger">
		Block
	</div> 
</template>

<script>
export default {
	data() {
		return {
			height: 50,
		};
	},
	computed: {
		heightModel: {
			get() {
				return this.height;
			},
			set(height) {
				this.height = height;
				this.changeHeight(height);
			},
		},
	},
	mounted() {
		if (this.height) {
			this.changeHeight(this.height);
		}
	},
	methods: {
		changeHeight(height) {
			this.$refs.myBlock.style.height = `${height}px`;
		},
	}
}
</script>

二、自定義指令 (custom directive)
常用的 v-model 就是一種指令(directive),你也可以自訂指令方便全域使用。若定義 focus,在 template 上就使用 v-focus
// Register a global custom directive called `v-focus`
Vue.directive('focus', {
  // When the bound element is inserted into the DOM...
  inserted: function (el) {
    // Focus the element
    el.focus()
  }
})

同理,自定義一個 v-height,來改變元件的高度:
<template>
	<input
		v-model.number="height"
		type="number">
	<div
		v-height="height"
		class="border border-danger">
		Block
	</div> 
</template>

<script>
export default {
	directives: {
		height: (el, binding) => {
			el.style.height = `${binding.value}px`;
		},
	},
	data() {
		return {
			height: 50,
		};
	},
}
</script>

完整的範例請可以參考:

See the Pen Vue.js Reference ID VS Custom Directives by chenuin (@chenuin) on CodePen.