Alex
Alex

Reputation: 49

Vue composition API renders {value: 0} instead of plain value for nested field

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

Answers (2)

tony19
tony19

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

Jesse Reza Khorasanee
Jesse Reza Khorasanee

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

Related Questions