I need access to DOM-element (set focus) which rendering through v-if
condition:
<template>
<input
v-if="isInputShow"
ref="input"
>
<button
v-else
@click="showInput"
>Show input</button>
</template>
import { ref } from 'vue'
export default {
setup() {
const isInputShow = ref(false)
const input = ref(null)
const showInput = () => {
if(!isInputShow.value) {
isInputShow.value = true
console.log(input.value) //null
}
}
return{
input,
isInputShow,
showInput
}
}
}
onMounted
hook doesn't work (conditional rendering).
Change v-if
condition on v-show
doesn't work (need to hide another element).
Maybe I should use reactive()
instead of ref()
? But how?
You can watch the input ref, it could give a more concise solution:
<script setup>
import { watch, ref } from 'vue'
const isInputShow = ref(false)
const input = ref(null)
watch(input, input => {
// if you show/hide the input with v-if, check it's not null
input && console.log(input);
});
</script>
<template>
<input
v-if="isInputShow"
ref="input"
>
<button
v-else
@click="isInputShow = true"
>Show input</button>
</template>
As mentioned by yoduh you could use nextTick()
also. But it returns a promise so async/await
would give a more clean solution imho:
<script setup>
import { nextTick, ref } from 'vue'
const isInputShow = ref(false)
const input = ref(null)
const showInput = async () => {
if(!isInputShow.value) {
isInputShow.value = true
await nextTick();
console.log(input.value)
}
}
</script>
<template>
<input
v-if="isInputShow"
ref="input"
>
<button
v-else
@click="showInput"
>Show input</button>
</template>