How to pass a ref to a method/function argument without unwrapping?

Viewed 1636

We're using the Vue Composition API and would like to pass a ref object, not just the value, as an argument to a function. Some code to clarify:

import { defineComponent, ref } from '@vue/composition-api'

export default defineComponent({
  setup() {
    const driverId = ref()
    const truckId = ref()

    const clearDriverId = () => {
      driverId.value = null
    }

The code above works fine, but we need to duplicate the function clearDriverId for the truckId too. That's why we would like to create something like this:

    const clearField = (field: Ref) => {
      field.value = null
    }

Accessed from the template:

<q-input
  label="Driver ID"
  v-model="driverId"
>
  <template v-slot:append>
    <q-icon
      name="close"
      @click.stop="clearField(driverId)"
    />
  </template>
</q-input>

Of course, this does not work because the ref driverId gets unwrapped when passed from the template to the function. What is the correct way to pass a complete ref object to a function?

1 Answers

One solution in setup() is to return an object/dictionary that contains all your refs (preventing their auto-unwrap), which could then be used to pass a specific ref to your function. A utility (toMyRefs() below) that returns the ref along with a ref dictionary would be helpful in minimizing repetitive code:

<template>
  <div>
    <button @click="clearField(myRefs.driverId)">Clear driverId</button>
    <button @click="clearField(myRefs.truckId)">Clear truckId</button>
    <button @click="clearField(myRefs.carId)">Clear carId</button>
    <button @click="clearField(myRefs.trainId)">Clear trainId</button>

    <pre>
      driverId: {{ driverId }}
      truckId: {{ truckId }}
      carId: {{ carId }}
      trainId: {{ trainId }}
    </pre>
  </div>
</template>

<script>
import { defineComponent, ref } from '@vue/composition-api'

const toMyRefs = refs => ({
  ...refs,
  myRefs: {
    ...refs
  }
})

export default defineComponent({
  setup() {
    const driverId = ref(1)
    const truckId = ref(2)
    const carId = ref(3)
    const trainId = ref(4)

    const clearField = (field) => {
      field.value = 0
    }

    return {
      ...toMyRefs({
        driverId,
        truckId,
        carId,
        trainId,
      }),
      clearField,
    }
  }
})
</script>

demo

Related