Adri H. M.
¿Alguien sabe cómo agregar una variable global en Vue 3?
en Vue 2 usamos esto en el main.js
archivo:
Vue.prototype.$myGlobalVariable = globalVariable
falda
El reemplazo más directo es app.config.globalProperties
. Ver:
https://vuejs.org/api/application.html#app-config-globalproperties
Entonces:
Vue.prototype.$myGlobalVariable = globalVariable
se convierte en:
const app = createApp(RootComponent)
app.config.globalProperties.$myGlobalVariable = globalVariable
Esto está enfocado a una aplicación particular en lugar de ser global como lo fue con Vue.prototype
. Esto es por diseño, todas las opciones de configuración ‘globales’ ahora están en el ámbito de una aplicación.
El RFC relevante está aquí:
https://github.com/vuejs/rfcs/blob/master/active-rfcs/0009-global-api-change.md
Propiedades añadidas a globalProperties
estará disponible a través de la instancia del componente para todos los componentes dentro de la aplicación. Entonces, si está utilizando la API de opciones, podrá acceder a ellas usando this.$myGlobalVariable
al igual que podrías con Vue.prototype
. También estarán disponibles en la plantilla sin la this.
p.ej {{ $myGlobalVariable }}
.
Si está utilizando la API de composición, aún podrá usar estas propiedades dentro de la plantilla, pero no tendrá acceso a la instancia del componente dentro setup
por lo que no se podrá acceder a estas propiedades allí.
Mientras que los hacks que involucran getCurrentInstance()
se puede utilizar para acceder globalProperties
dentro setup
esos hacks implican el uso de API no documentadas y no son el enfoque recomendado.
En cambio, a nivel de aplicación provide
/inject
(también discutido en ese RFC) se puede utilizar como una alternativa a Vue.prototype
:
const app = createApp(RootComponent)
app.provide('myGlobalVariable', globalVariable)
En el componente descendiente, se puede acceder a esto usando inject
. por ejemplo, con <script setup>
:
<script setup>
import { inject } from 'vue'
const myGlobalVariable = inject('myGlobalVariable')
</script>
O con un explícito setup
función:
import { inject } from 'vue'
export default {
setup() {
const myGlobalVariable = inject('myGlobalVariable')
// Expose it to the template, if required
return {
myGlobalVariable
}
}
}
O con la API de Opciones:
export default {
inject: ['myGlobalVariable']
}
Documentos: https://vuejs.org/api/application.html#app-provide
La idea aquí es que el componente pueda declarar explícitamente la propiedad en lugar de heredarla por arte de magia. Eso evita problemas como colisiones de nombres, por lo que no es necesario utilizar un $
prefijo. También puede ayudar a aclarar de dónde proviene exactamente una propiedad.
Es común para el inject
función para ser envuelto en un componible. por ejemplo, el useRoute
componible expuesto por Vue Router es solo un envoltorio inject
.
Además de globalProperties
y provide
/inject
hay varias otras técnicas que podrían usarse para resolver los mismos problemas que Vue.prototype
. Por ejemplo, módulos ES, tiendas o incluso mixins globales. Estas no son necesariamente respuestas directas a la pregunta específica publicada aquí, pero he entrado en más detalles describiendo los diversos enfoques en:
https://skirtles-code.github.io/vue-examples/patterns/global-properties.html
El enfoque que prefiera dependerá de sus circunstancias.
-
esto funciona con las clases? no parece funcionar para mí
– David 天宇 Wong
12 de septiembre de 2021 a las 4:30
-
¿Y cómo se accede a las variables globales desde los componentes secundarios (en ambos casos)? es directamente llamando
this.myGlobalVariable
?– Mehdi
15 de diciembre de 2021 a las 8:10
-
¿Hay alguna forma de declarar variables globales desde fuera del archivo de creación de la aplicación principal? En Vue 2 solía importar Vue y luego declarar nuevas variables globales. Estoy luchando ahora ya que necesito el
app
creado porcreateApp
.– Mehdi
15 de diciembre de 2021 a las 8:17
-
M3HD1: puede crear una función que tome la aplicación (
app
en el código anterior) como un parámetro y hace elprovide
(es decir, doProv = function(app) { app.provide(…); } y luego simplemente impórtelo y llámelo en main.js o donde sea que haga la creación/configuración de su aplicación.– Dov Rosenberg
23 de enero de 2022 a las 13:41
-
Su argumentación es sólida, pero notablemente no enfatiza la gran desventaja del nuevo enfoque. Necesitas una línea extra, es decir
inject
en cada componente en el que desee acceder a una variable global en CAPI.– ViBoNaCci
19 de marzo a las 8:34
Zack Plauche
Cómo agregar una variable global usando Vue 3 y vue-cli (o Vite)
Nota: Puede soltar el signo de dólar de su $globalVariable
y solo usa globalVariable
al igual que en la documentación.
Inicialmente, su archivo main.js se parece a esto (agregando enrutador para un caso de uso común):
import { createApp } from 'vue'
import { App } from './App.vue'
import { router } from './router'
createApp(App).use(router).mount('#app')
Para usar agregar la variable global usando Vue 3 y el vue-cli o Vite:
import { createApp } from 'vue'
import { App } from './App.vue'
import { router } from './router'
// 1. Assign app to a variable
let app = createApp(App)
// 2. Assign the global variable before mounting
app.config.globalProperties.globalVar="globalVar"
// 3. Use router and mount app
app.use(router).mount('#app')
Luego, para acceder a las variables en componentes como este:
<script>
export default {
data() {
return {
myVar: this.globalVar
}
}
}
</script>
como en la plantilla como esta:
<template>
<h1>{{ globalVar }}</h1>
</template>
Y eso es. ¡Feliz codificación!
Acerca de las variables globales y la API de composición
De acuerdo con la muy parte inferior de la respuesta de samayo en este postlas variables globales solo están disponibles en la API de opciones.
Citando la parte inferior de su respuesta:
Nota: Esto es solo para la API de opciones. Evan You (creador de Vue) dice: “config.globalProperties está pensada como una vía de escape para replicar el comportamiento de Vue.prototype. En las funciones de configuración, simplemente importe lo que necesita o use explícitamente proporcionar/inyectar para exponer las propiedades en la aplicación.
-
oye eso es increible!! ¡¡muchas gracias!! =)
– zergski
29 sep 2021 a las 19:03
-
Prefijar las variables con algún tipo de “carácter especial” hace que sea más fácil indicar en el código que esta variable es realmente especial y probablemente proviene de otro lugar. Esto hace que los codificadores sean más conscientes y que el desarrollo sea menos propenso a errores.
– Coreo
9 de noviembre de 2021 a las 13:16
-
@Coreus, ¿hay documentación específica que hable sobre esto?
– Zack Plauché
10 de noviembre de 2021 a las 9:39
-
No, pero es una práctica común para las cosas que contaminan el ámbito global. Piense en jQuery, por ejemplo, y su $. El enfoque también se usó comúnmente en los documentos de Vue 2. Como siempre, eres libre de usar lo que quieras, de la misma manera que eres libre de salirte del camino en lugar de seguirlo. Probablemente deberías buscar la Piedra de Rosetta. La experiencia nos dice que hacer que se destaquen (de alguna manera) hace que su significado sea más fácil de ver.
– Coreo
16 de noviembre de 2021 a las 12:19
-
@db2 Recién actualizado. Aparentemente, esta no es una función para la API de composición.
– Zack Plauché
26 de diciembre de 2021 a las 19:13
Boussadjra Brahim
recomiendo usar provide/inject
enfoque de la siguiente manera:
en principal.js:
import {createApp} from 'vue'
let app=createApp({
provide:{
globalVariable:123
}
}).$mount('#app')
en algún componente hijo o nieto hacer:
export default{
name:'some-compo',
inject:['globalVariable'],
//then access this.globalVariable as property in you component
...
}
para la composición de la API y la configuración del script:
import { inject } from 'vue'
let globalVar=inject('globalVariable')
-
createApp en mi ejemplo se le está pasando un componente, que tiene
. Entonces, ¿cómo pasar proporcionar en este caso? – David 天宇 Wong
12 de septiembre de 2021 a las 4:19
-
¿Cómo puedo lograr algo similar a esto dentro de una clase (no un componente), quiero decir, cómo puedo usar inyectar dentro de una clase?
– yasseros
12 de noviembre de 2021 a las 10:31
-
¿Es posible inyectar múltiples variables en una línea?
– WM
5 de enero de 2022 a las 20:17
-
@WM, sí, podría con las opciones api, pero en la composición uno debe asignar cada elemento inyectado en una variable específica
– Boussadjra Brahim
5 de enero de 2022 a las 21:28
-
Actualmente solo está vinculando a la página de proporcionar/inyectar API de opciones, también debe vincular a la página de proporcionar/inyectar API de composición: vuejs.org/api/composition-api-dependencia-inyección.html
– usuario17408941
7 de julio de 2022 a las 12:27
Si es posible, debe usar importaciones o proporcionar/inyectar. Otra forma de definir variables/funciones globales y usarlas sería usando globalProperties (aunque esto parece considerarse más como un antipatrón). Pero si una biblioteca que usa usa globalProperties, entonces puede usarla así. Esto también funciona con funciones globales.
const app = Vue.createApp({})
app.config.globalProperties.$http = () => {} // global function
app.config.globalProperties.$globalVariable="Jimmy" // global variable
1. Uso de la API de opciones
mounted() {
console.log(this.$globalVariable)
}
2. Usando el método de configuración
<script setup>
import { getCurrentInstance } from 'vue'
const app = getCurrentInstance()
const progressBar = app.appContext.config.globalProperties.$globalVariable
console.log(this.$globalVariable)
</script>
teresa
Para aquellos de ustedes que están confundidos acerca de cómo acceder globalProperties
en el setup()
método, puede utilizar getCurrentInstance()
como en la siguiente documentación.
https://v3.vuejs.org/api/composition-api.html#getcurrentinstance
-
De la documentación: “getCurrentInstance solo se expone para casos de uso avanzado, generalmente en bibliotecas. Se desaconseja encarecidamente el uso de getCurrentInstance en el código de la aplicación. NO lo use como una vía de escape para obtener el equivalente de esto en la API de composición”.
– Coreo
9 de noviembre de 2021 a las 13:18
Vista 3:
import { getCurrentInstance } from "vue";
const { proxy } = getCurrentInstance();
“proxy” contendrá el valor de globalProperties. Por ejemplo:
app.config.globalProperties.$toast = {...}
y luego:
proxy.$toast.success()
-
De la documentación: “getCurrentInstance solo se expone para casos de uso avanzado, generalmente en bibliotecas. Se desaconseja encarecidamente el uso de getCurrentInstance en el código de la aplicación. NO lo use como una vía de escape para obtener el equivalente de esto en la API de composición”.
– Coreo
9 de noviembre de 2021 a las 13:18
Zach Jensz
En mi caso, tuve que crear una var global y obtener los datos de un script.
Se utiliza proporcionar e inyectar:
En main.js
:
import { createApp } from 'vue'
import App from './App.vue'
const app = createApp(App);
app.provide('message',document.querySelector('script[name="nameSCRIPT"]').innerHTML.split('=').slice(1).join('=').slice(1,-1));
app.mount('#app')
En index.html
:
<script name="nameSCRIPT">nameSCRIPT="HELLO"</script>
En componente hijo:
inject:['message'],
mounted(){
console.log(this.message)
},
-
Es muy probable que su solución a veces se rompa con un error:
TypeError: Cannot read properties of null (reading 'innerHTML')
. En general, DOM se trata de DISPLAY, pero no de almacenamiento de datos. Entonces es más fácil escribir una variable paraself
y leer desde allí, aunque esto es malo por varias razones– Alejandro
9 de marzo a las 8:41
stackoverflow.com/a/40897670/2815635
– Niklesh Raut
26 de julio de 2020 a las 13:19
Puede usar Vuex para manejar todos los datos globales
– nassim miled
26 de julio de 2020 a las 13:20
Sí, por supuesto, puedo usar la tienda o usar una combinación global, pero estoy pidiendo usar un prototipo.
– Adri HM
26 de julio de 2020 a las 13:21