# Refs

Cette section utilise la syntaxe des composant à fichier unique pour les examples

# ref

Prend une valeur interne et renvoie un objet ref réactif et modifiable. L'objet ref a une seule propriété .value qui pointe vers la valeur interne.

Exemple:

const count = ref(0)
console.log(count.value) // 0

count.value++
console.log(count.value) // 1
1
2
3
4
5

Si un objet est assigné comme une valeur ref, l'objet est rendu profondément réactif par la méthode reactive.

Typage:

interface Ref<T> {
  value: T
}

function ref<T>(value: T): Ref<T>
1
2
3
4
5

Parfois, nous pouvons avoir besoin de spécifier des types complexes pour la valeur interne d'une ref. Nous pouvons le faire de manière succincte en passant un argument générique lors de l'appel de ref pour remplacer l'inférence par défaut:

const foo = ref<string | number>('foo') // le type de foo: Ref<string | number>

foo.value = 123 // ok!
1
2
3

Si le type du générique est inconnu, il est recommandé d'effectuer un cast ref à Ref<T>:

function useState<State extends string>(initial: State) {
  const state = ref(initial) as Ref<State> // state.value -> State extends string
  return state
}
1
2
3
4

# unref

Renvoie la valeur interne si l'argument est une ref, sinon renvoie l'argument lui-même. Ceci est une "sugar function" pour val = isRef(val) ? val.value : val.

function useFoo(x: number | Ref<number>) {
  const unwrapped = unref(x) // unwrapped est garanti d'être un number maintenant
}
1
2
3

# toRef

Peut être utilisé pour créer une ref pour une propriété sur un objet réactif source. La référence peut ensuite être transmise, en conservant la connexion réactive à sa propriété source.

const state = reactive({
  foo: 1,
  bar: 2
})

const fooRef = toRef(state, 'foo')

fooRef.value++
console.log(state.foo) // 2

state.foo++
console.log(fooRef.value) // 3
1
2
3
4
5
6
7
8
9
10
11
12

toRef est utile lorsque vous souhaitez passer la ref d'un prop à une fonction de composition:

export default {
  setup(props) {
    useSomeFeature(toRef(props, 'foo'))
  }
}
1
2
3
4
5

toRef retournera une ref utilisable même si la propriété source n'existe pas encore. Cela le rend particulièrement utile lorsque vous travaillez avec des props optionnels, qui ne seraient pas repris par toRefs.

# toRefs

Convertit un objet réactif en un objet simple où chaque propriété de l'objet résultant est une ref pointant vers la propriété correspondante de l'objet d'origine.

const state = reactive({
  foo: 1,
  bar: 2
})

const stateAsRefs = toRefs(state)
/*
Type de stateAsRefs:

{
  foo: Ref<number>,
  bar: Ref<number>
}
*/

// La ref et la propriété originale sont "liés"
state.foo++
console.log(stateAsRefs.foo.value) // 2

stateAsRefs.foo.value++
console.log(state.foo) // 3
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

toRefs est utile lorsqu'on retourne un objet réactif depuis une fonction de composition afin que le composant qui l'utilise puisse déstructurer/spread l'objet retourné sans perdre la réactivité:

function useFeatureX() {
  const state = reactive({
    foo: 1,
    bar: 2
  })

  // opération logique sur state

  // convertir en refs quand on le retourne
  return toRefs(state)
}

export default {
  setup() {
    // Peut destructurer sans perdre la reactivité
    const { foo, bar } = useFeatureX()

    return {
      foo,
      bar
    }
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

toRefs ne générera des refs que pour les propriétés incluses dans l'objet source. Pour créer une ref pour une propriété spécifique, utilisez plutôt toRef.

# isRef

Vérifie si une valeur est un objet ref.

# customRef

Crée une ref personnalisée avec un contrôle explicite sur le suivi de ses dépendances et le déclenchement des mises à jour. Il attend une factory function qui reçoit les fonctions track ettrigger comme arguments et doit retourner un objet avec get etset.

  • Exemple utilisant un custom ref pour implémenter debounce avec v-model:

    <input v-model="text" />
    
    1
    function useDebouncedRef(value, delay = 200) {
      let timeout
      return customRef((track, trigger) => {
        return {
          get() {
            track()
            return value
          },
          set(newValue) {
            clearTimeout(timeout)
            timeout = setTimeout(() => {
              value = newValue
              trigger()
            }, delay)
          }
        }
      })
    }
    
    export default {
      setup() {
        return {
          text: useDebouncedRef('hello')
        }
      }
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26

Typage:

function customRef<T>(factory: CustomRefFactory<T>): Ref<T>

type CustomRefFactory<T> = (
  track: () => void,
  trigger: () => void
) => {
  get: () => T
  set: (value: T) => void
}
1
2
3
4
5
6
7
8
9

# shallowRef

Crée une ref qui traque sa propre mutation .value mais ne rend pas sa valeur réactive.

const foo = shallowRef({})
// la mutation de la valeur de ref est reactive
foo.value = {}
// mais la valeur ne sera pas convertie.
isReactive(foo.value) // false
1
2
3
4
5

Voir aussi: Créer des valeurs reactives autonomes en tant que refs

# triggerRef

Exécute manuellement n'importe quel effet lié à shallowRef.

const shallow = shallowRef({
  greet: 'Hello, world'
})

// La console affiche "Hello, world" une seule fois au 1er passage
watchEffect(() => {
  console.log(shallow.value.greet)
})

// Ceci ne déclenchera pas l'effet car la ref est shallow
shallow.value.greet = 'Hello, universe'

// Dans la console "Hello, universe"
triggerRef(shallow)
1
2
3
4
5
6
7
8
9
10
11
12
13
14

Voir aussi: Computed et Watch - watchEffect

Deployed on Netlify.
Dernière Mise-à-jour: 3/22/2021, 5:50:52 PM