Reputation: 23214
I'm stuck trying to understand how I can get reactive values when using functions in Vue.
I have a simple case like so:
<v-simple-checkbox :value="isSelected(item)" @input="toggleSelect(item)" />
isSelected
and toggleSelect
are methods (or rather functions exposed via Vue Composition API).
they are defined as so:
let selection = {};
function toggleSelect(item) {
selection[item.id] = !selection[item.id]
}
function isSelected(item) {
return !!selection[item.id];
}
return {
isSelected,
toggleSelect,
other exposed things...
}
When clicking the checkbox, I see that all state is updated.
But as :value
binds to a function. it doesn't trigger update of the view.
This is basically the issue of "computed with arguments" and I don't find any real answer to it.
I've tried with $forceUpdate
but no luck there either.
Upvotes: 1
Views: 6475
Reputation: 37903
But as
:value
binds to a function, it doesn't trigger update of the view.
This is simply not true. It doesn't matter whether you bind to an inline JS expression (like :value="!!selection[item.id]"
) or to a function returning result of the same expression as in your example. Vue just executes render function (compiled from template) and monitors all reactive data. If some reactive data is used during rendering, Vue knows that whenever this data changes in the future, it should run re-render. And it doesn't matter whether data is "touched" by simple expression or calling function or calling multiple nested functions. Doesn't matter at all. What matters is whether your data is reactive
For selection
to be reactive, you must create it and use it like this:
const state = reactive({
selection: {}
})
function toggleSelect(item) {
state.selection[item.id] = !state.selection[item.id]
}
function isSelected(item) {
return !!state.selection[item.id];
}
Don't forget to import { reactive } from '@vue/composition-api'
I assume you are using this package for your experiments. It's new composition API but implemented on top of Vue 2. Because of this, is has same Change Detection Caveats. Problem in this case is adding new properties to empty object selection
. After adding initial values, code works as expected....
const state = reactive({
selection: {
1: false,
2: true
}
});
In Vue 3 this won't be needed as it will use proxies for change detection...
Upvotes: 4