Reputation: 49
I'm trying to create a component that can be used via destructuring and as js object.
Destructuring works fine, but with js object, I'm forced to write obj.field.value
instead of just obj.field
. Is it expected behavior?
I'm using composition-api plugin.
Playground: https://jsfiddle.net/3mzve8oy/21/
<div id="app">
<h2 @click="ctx.fn">{{ ctx.counter }} {{counter}} </h2>
</div>
const { reactive, toRefs } = VueCompositionAPI;
const useCounter = () => {
const ctx = reactive({
counter: 2,
// ...
});
const fn = () => {
console.log('Called', ctx.counter);
}
setInterval(() => ctx.counter += 1, 1000);
return {...toRefs(ctx), fn};
}
new Vue({
el: "#app",
setup() {
const ctx = useCounter();
const { counter } = useCounter();
return { ctx, counter };
}
})
Expected output: 0 0
Actual output: { "value": 0 } 0
Upvotes: 1
Views: 268
Reputation: 138356
Yes, this is expected behavior. See Ref Unwrapping docs, which describe your exact scenario:
When a ref is returned as a property on the render context (the object returned from setup()) and accessed in the template, it automatically shallow unwraps the inner value. Only the nested ref will require
.value
in the template:<template> <div> <span>{{ count }}</span> <button @click="count ++">Increment count</button> <button @click="nested.count.value ++">Nested Increment count</button> </div> </template> <script> import { ref } from 'vue' export default { setup() { const count = ref(0) return { count, nested: { count } } } } </script>
Upvotes: 1
Reputation: 3471
This is my first time seeing vue-composition-api
, but in their docs it looks like they use value
as design choice in objects to preserve reactivity on the object if it gets passed around the app.
see here: https://v3.vuejs.org/guide/composition-api-introduction.html#setup-component-option
ref takes the argument and returns it wrapped within an object with a value property, which can then be used to access or mutate the value of the reactive variable:*
import { ref } from 'vue'
const counter = ref(0)
console.log(counter) // { value: 0 }
console.log(counter.value) // 0
counter.value++
console.log(counter.value) // 1
Upvotes: 0