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
のレンダリングを待つことでも対応できます。