En main.js tengo algo como esto:

import { myUtilFunc} from './helpers';
Object.defineProperty(Vue.prototype, '$myUtilFunc', { value: myUtilFunc });

De esta manera, tengo acceso a myUtilFunc en toda la aplicación con this.$myUtilFunc

Pero, ¿cómo puedo lograr lo mismo en el método setup() en Vue 3 si no tengo acceso a this?

4
Stanislav 13 feb. 2020 a las 10:41

2 respuestas

La mejor respuesta

En Vue 3, setup tiene un segundo argumento opcional para context. Puede acceder a la instancia de Vue a través de context.root en lugar de this:

setup(props, context) {
  context.root.$myUtilFunc  // same as `this.$myUtilFunc` in Vue 2
}

Cosas a las que puede acceder a través de context:

context.attrs
context.slots
context.parent
context.root
context.emit
4
Dan 13 feb. 2020 a las 09:15

Si bien la respuesta de Dan es correcta, me gustaría proporcionar una alternativa mencionada en los comentarios a la respuesta aceptada. Hay pros y contras para cada uno, por lo tanto, debe elegir según sus necesidades.

Para entender por qué funciona el siguiente código, es importante recordar que las propiedades proporcionadas son transitivas en el árbol de componentes. Es decir. inject('foo') buscará 'foo' en cada padre que suba por la jerarquía hasta app; No es necesario declarar nada en los contenedores intermedios.

Entonces, podemos escribir algo como esto:

main.js

import { createApp } from 'vue'
import App from './App.vue'

const globalDateFormatter = (date) => {
    return '[' + date.toLocaleString() + ']'
}

const app = createApp(App)
app.provide('globalDateFormatter', globalDateFormatter) // <-- define here
app.mount('#app')

Y luego, en algunos DeepDownComponent.vue :

<template>
  <p> {{ fmt(new Date()) }} </p>
</template>

<script>
import { inject } from 'vue'
export default {
    setup(){
        const fmt = inject('globalDateFormatter', x => x.toString()) 
        //           ^-- use here, optional 2nd parameter is the default
        return {fmt}
    }
}
</script>

Obviamente, puedes usar

provide<T>(key: InjectionKey<T> | string, value: T): void

Y

inject<T>(key: InjectionKey<T> | string, defaultValue: T): T

En cualquier parte de su código, no tiene que ser app.provide()

También puede proporcionar valores, incluso la tienda global, como esta, simplemente no olvide usar ref() o reactive() según sea necesario.

En resumen, cada vez que prefiera la inyección de dependencia, proporcionar / inyectar son sus amigos.

0
Alex Pakka 11 abr. 2020 a las 05:12