Vue3 migration: problems replacing fluid $refs array with function ref, constant duplicates, and $refs not being reactive.
When migrating from Vue2 to Vue3, one of the major changes is the way we handle refs. In Vue2, we used to use $refs
to access the DOM elements or components, but in Vue3, we have to use Composition API's ref
function or reactive
with readonly
property to create refs.
However, there are some common issues that developers might face during the migration process:
- Problems replacing fluid $refs array with function ref:
In Vue2, we were used to having a $refs
object that we could access any DOM element or component by its key. But in Vue3, we need to use ref
function to create a ref for each element or component, and then store them in an array or an object.
For example, in Vue2:
<template>
<div>
<button ref="button1">Button 1</button>
<button ref="button2">Button 2</button>
</div>
</template>
<script>
export default {
methods: {
focusButton(index) {
this.$refs[index].focus();
},
},
};
</script>
In Vue3, we need to use ref
function to create refs for each button and then store them in an array:
<template>
<div>
<button ref="button1">Button 1</button>
<button ref="button2">Button 2</button>
</div>
</template>
<script setup>
import { ref } from 'vue';
const buttons = [ref(null), ref(null)];
function focusButton(index) {
buttons[index].value.focus();
}
</script>
- Constant duplicates:
Another issue that developers might face is when they try to create a ref for a constant value. In Vue2, we could create a ref for a constant value, but in Vue3, we cannot do that directly. Instead, we need to create a ref and assign the constant value to it.
For example, in Vue2:
<template>
<div>
<p ref="title">Hello World</p>
</div>
</template>
<script>
export default {
data() {
return {
title: 'Hello Vue',
};
},
};
</script>
In Vue3, we need to create a ref and assign the constant value to it:
<template>
<div>
<p ref="title">{{ title }}</p>
</div>
</template>
<script setup>
import { ref } from 'vue';
const title = ref('Hello Vue');
</script>
- $refs not being reactive:
Finally, another common issue is that $refs
in Vue2 were reactive by default, but in Vue3, we need to make sure that the refs are reactive by using reactive
or readonly
property.
For example, in Vue2:
<template>
<div>
<p ref="title">{{ title }}</p>
<button @click="focusTitle">Focus title</button>
</div>
</template>
<script>
export default {
data() {
return {
title: 'Hello Vue',
};
},
methods: {
focusTitle() {
this.$refs.title.focus();
},
},
};
</script>
In Vue3, we need to make sure that the refs are reactive by using reactive
or readonly
property:
<template>
<div>
<p ref="title">{{ title }}</p>
<button @click="focusTitle">Focus title</button>
</div>
</template>
<script setup>
import { ref, reactive } from 'vue';
const title = ref('Hello Vue');
const titleReactive = reactive({ title: 'Hello Vue' });
function focusTitle() {
title.value.focus();
titleReactive.title.focus();
}
</script>
In conclusion, migrating from Vue2 to Vue3 requires some adjustments when it comes to handling refs. By understanding the differences and the solutions to common issues, developers can make a smooth transition to Vue3.