How does Computed work in Vue 3 script setup?

In <template>:

Getter only:

  • {{ myVal }}
  • <p v-text="myVal" />

Getter and setter:

  • <input v-model="myVal">

Important: Do not use myVal.get() or myVal.set(value)! Use:

  • getting: myVal
  • setting (assignment): myVal = value

In <script setup>:

Getter only:

const someReactiveRef = ref(null)
const myVal = computed(() => someReactiveRef.value)

Getter & setter:

const someReactiveRef = ref(null)

const myVal = computed({
  get() {
    return someReactiveRef.value
  },
  set(val) {
    someReactiveRef.value = val
  }
})
// myVal can now be used in `v-model`

When the reactive ref is coming from a reactive() object’s property, you don’t need the .value in either the setter or the getter. Example:

const store = reactive({
  someProp: null
})

const myVal = computed({
  get() {
    return store.someProp
  },
  set(val) {
    store.someProp = val
  }
})

Remember you can always use computed inside reactive. Example:

const { createApp, reactive, computed, toRefs } = Vue
createApp({
  setup() {
    const state = reactive({
      firstName: 'John W.',
      lastName: 'Doe',

      // getter + setter
      fullName: computed({
        get() {
          return [state.firstName, state.lastName].join(' ')
        },
        set(val) {
          const [last, ...rest] = val.split(' ').reverse()
          state.firstName = rest.reverse().join(' ')
          state.lastName = last
        }
      }),

      // getter only:
      name: computed(() => state.fullName)
    })
    return toRefs(state)
  }
}).mount('#app')
<script src="https://unpkg.com/vue@3.2.40/dist/vue.global.prod.js"></script>
<div id="app">
  <input v-model="firstName" />
  <input v-model="lastName" />
  <input v-model="fullName" />
  <pre v-text="{ firstName, lastName, fullName, name }"></pre>
</div>

Important notes:

  • when passing a non-reactive reference to a computed, Vue will warn you (the computed wrapper is unnecessary).
  • when passing it a ref which contains a cyclic dependency (e.g: a component instance) Vue will again warn you and advise on using either shallowRef or markRaw.

Leave a Comment

Hata!: SQLSTATE[HY000] [1045] Access denied for user 'divattrend_liink'@'localhost' (using password: YES)