Vue.js(Nuxt.js)にて、 v-if使用時に$refsがundefinedになってしまう時の対処法になります。
v-if使用時$refsがundefinedになってしまう
<template>
<div>
<input v-if="isInputName" ref="inputName" type="text" name="name" />
<button @click="inputFocus">編集</button>
</div>
</template>
<script lang="ts">
import Vue from 'vue'
export default Vue.extend({
data() {
return {
isInputName: false
}
},
methods: {
inputFocus() {
this.isInputName = true
const inputName = this.$refs.inputName
inputName.focus()
}
}
})
</script>
上記のコード例ですと、TypeError: Cannot read property 'focus' of undefinedと言うエラーが出ます。
v-ifはレンダリングされないので、$refsでは取得できずにundefinedとなる為です。
v-showに変更すればundefinedにはなりません。
v-ifのレンダリングを待つことで解決
v-ifによるレンダリングを待つことで解決することができます。
setTimeout
<script lang="ts">
import Vue from 'vue'
export default Vue.extend({
data() {
return {
isInputName: false
}
},
methods: {
inputFocus() {
this.isInputName = true
setTimeout(() => {
const inputName = this.$refs.inputName
inputName.focus()
}, 100)
}
}
})
</script>
setTimeoutで処理を遅らせることで、$refsがundefinedになるのを防げます。
async/await
<script lang="ts">
import Vue from 'vue'
export default Vue.extend({
data() {
return {
isInputName: false
}
},
methods: {
async inputFocus() {
await (this.isInputName = true)
const inputName = this.$refs.inputName
inputName.focus()
}
}
})
</script>
async/awaitでv-ifのレンダリングを待つことでも対応できます。