I need to have a ref that will hold an array for my Vue 3 app written using composition API and typescript.
The array is used in a computed where I will push in some objects. At the moment I’m unable to achieve this I will get this error on push when I target the array in computed
Property ‘push’ does not exist on type ‘Ref<[]>’
This is the code I’m using:
const myArray = ref<[]>([]);
const myComputed = computed(() => {
if (propertyOne) {
myArray.push({ id: 'autoId0', path: 'myPath' })
}
return myArray
})
I’ve also tried by using a let myArray = []
inside the computed but will be not populated. Any suggestions?
4
Let’s first address your error of:
Property ‘push’ does not exist on type ‘Ref<[]>’
Consider these examples:
const stringValue: string = ''
const numberValue: number = 123
If you don’t explicitly add the type, typescript will use the implied type based on the initial value i.e
const impliedStringType = ''
const impliedNumberType = 123
That being said if you do:
const myArrayRef = ref([])
The implied type is Ref<[]>
Type Ref
is NOT an array but an “object” containing an array.
Docs about Ref
:
- https://vuejs.org/api/reactivity-core.html#ref
- https://vuejs.org/guide/essentials/reactivity-fundamentals.html#declaring-reactive-state-1
To get the actual value from a ref, you access it via the value
property.
Thus to make push
work:
myArrayRef.value.push()
Next to address your usage of computed
,
Computed usually are derived values and are free from any mutations.
If your derived value is an array with extra value based on a critieria, copy the array, mutate that, and return that instead.
Docs: https://vuejs.org/guide/essentials/computed.html#best-practices
In other words:
const myArrayRef = ref([])
const myComputedArray = computed(() => {
// Regular array. Not a Ref.
// A new array with values from the original array.
const computedArray = [...myArrayRef.value]
if (criteria) {
computedArray.push(123)
}
return computedArray
})
Otherwise, what you are doing is whenever the criteria is met, the original array gets push
.
So if the following scenario happens:
- Criteria: true
- Criteria: false
- Criteria: true
Your original array now has 2 new values because you are mutating the original array.
Here is a simple Vue Playground demo and another using object Vue Playground demo
8