vuejs3vue-props

in vue 3.3 alpha 4 props destructure


I am trying vue 3.3.0 alpha-4 new feature but there is one problem. after destructure of props, normally it should keep their reactivity. but only field keep it.

const {
  field,
  dialog,
} = defineProps<{
  field: {name: string, value: string},
  dialog: boolean
}>()

onMounted((): void => {
  nextTick(async (): Promise<void> => {
    dialog = false // not working
    field.name = "data" // works
    console.log(field, dialog)
  })
})

errors says for dialog

Uncaught (in promise) TypeError: Assignment to constant variable.


Solution

  • At first, the props are read-only, so the way you are trying to change the dialog value is per se wrong.

    Second, there is the Reactive Props Destructure part of the Vue Docs, describing exactly what you are observing:

    1. Similar to .value, you need to always access props as props.x in order to retain reactivity. This means you cannot destructure defineProps because the resulting destructured variables are not reactive and will not update.

    And, at the end.

    This has nothing to do with the Vue Version 3.3.0-alpha.4. You can try the SFC Playground and switch the Vue version to see, that the props destructuring behave the same, independently from the version you choose.

    UPDATE

    I forgot to state, that you can also use toRefs(), to destruct your props preserving reactivity.

     const props = defineProps<{
        field: {name: string, value: string},
        dialog: boolean }>()
    
     const { field, dialog } = toRefs(props)
    

    And then use dialog.value to access the value. But they still remain readonly and you will get the Vue Warning, if you try to change the value.

    [Vue warn] Set operation on key "dialog" failed: target is readonly.[object Object]

    Check this SFC Playground