38

I have this vue js component:

<template>
    <div>
hello world
    </div>
</template>

<script>
  export default {
    name: 'mycomp',
    data: function () {
      console.error("window.google_recaptcha_public_key", window.google_recaptcha_public_key);
      return {

      }
    },
    mounted() {
      let app = this;
      console.error("window.google_recaptcha_public_key2", window.google_recaptcha_public_key);

    },
  }
</script>

<style scoped lang="scss">
</style>

returns:

window.google_recaptcha_public_key undefined 
window.google_recaptcha_public_key2 undefined

where can I leave painless and happy all global configuration?

notice this configuration lives in my laravel backend. So I wont copy paste all values from the backend to the front end

1
  • If you do this window.google_recaptcha_public_key on browser console, do you get any value? Commented Jan 13, 2019 at 8:34

6 Answers 6

39

U can use Vue.prototype in main.js file, or in file you import Vue

Vue.prototype.Hereanyname = window.hereanyname;

and in your Vue application, you can use it

Hereanyname.thefunction

Real example on Laravel

in main.js

import Vue from 'vue';
Vue.prototype.Routes = window.routes;

new Vue({
    el: '#app',
    template: '<App/>',
    components: {App}
});

in your application

:href="Routes.route('laravel.route.here')"

So for your case

import Vue from 'vue';
Vue.prototype.GoogleRecaptcha = window.google_recaptcha_public_key;

new Vue({
    el: '#app',
    template: '<App/>',
    components: {App}
});

inside application

mounted() {
  console.log(this.GoogleRecaptcha)
}
Sign up to request clarification or add additional context in comments.

Comments

25

In Vue3, you no longer have the global Vue instance, so you need to assign the window as a global property on your app...

// main.js
app.config.globalProperties.window = window

Then in your components, window will just work.

This info is from an impeccable source.

1 Comment

horrible way to do it honestly e.g. that you are forced to do it this way... e.g. horrible that this isn't more obvious to do. Seems very unpragmatic
11

You should save your window variable in Vue.prototype

main.js

Vue.prototype.$authUser = window.authUser;

After that, you can access your data as follows:

Vue template

<div v-text="$authUser.name"></div>

Vue script

let name = this.$authUser.name;

Comments

6

Provide/Inject works nicely. Here's an example with Vue 3:

main.js

const app = createApp(App)
app.provide('recaptcha_key', window.google_recaptcha_public_key)
app.mount('#app')

MyComponent.vue

<script setup>
const { inject } from 'vue'
const recaptchaKey = inject('recaptcha_key')
</script>

Comments

2

window is available in the vuex store. This may help if you need to mutate the window property synchronously with other actions/mutations, give you a chance to validate what goes into it, or catch an error if the variable you intend to put there isn't available.

export default new Vuex.store({
  state: {
    windowFoo: window.foo,
    googleRecaptcha: window.google_recaptcha_public_key
  },
  getters: {
    windowFoo: (state) => state.windowFoo,
    googleRecaptcha: (state) => state.googleRecaptcha
  },
  actions: {
    barThenFooThenBaz({ commit }, { foo }) {
        // ... do some other required actions first
        commit("setWindowFoo", foo);
       // ... do some dependent actions next
    }
  },
  mutations: {
    setWindowFoo(state, foo) {
      state.windowFoo = foo;
    }
  }
});

Then from your Single File Component...

//....
computed: {
  windowFoo() {
    return this.$store.getters.windowFoo;
  },
  googleRecaptcha() {
    return this.$store.getters.googleRecaptcha;
  }
},
methods: {
  async barThenFooThenBaz(foo) {
     await this.$store.dispatch({
       type: "barThenFooThenBaz",
       foo: foo
     });
     // ... do something dependent on windowFoo being set
  }
}
//....

Although the other answers here are totally acceptable, I've had issues using the Vue instance with Vue.prototype in main.js as our project has gotten larger, so I hope this helps!

Comments

0

Another answer that is IMO cleaner and does not involve polluting the Vue global object:

<template>
    <div>
      {{ window.something }}
    </div>
</template>

<script>
  export default {
    name: 'mycomp',
    data: function () {
      return {
        window = document.defaultView
      }
    },
    mounted() {
      console.log(this.window.something);
    },
  }
</script>

window is not available to the Vue instance but document is, and you can reference the defaultView to get the window. In almost all cases this will refer to the same global window instance available outside of Vue's component scope.

I expect ( but haven't tested ) that the window object would not be reactive: you would need to use a computed value alongside another reactive value to get that.

1 Comment

window = document.defaultView syntax is wrong and it's unclear why window itself couldn't be used. There's a problem with accessing it in a template, not in a script

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.