user2154171
user2154171

Reputation: 165

Use global variable in vue template

I'm trying to use a global variable in my vue template. I'm trying to use it without setting it in the data fields, because they're actually some global constants.

<template v-if="item.WheelDrive === WHEEL_DRIVE.ALLROAD">

this will give me the "Property or method is not defined on the instance but referenced during render" error.

Is it possible to direct vue not to try and bind WHEEL_DRIVE here?

Upvotes: 14

Views: 12738

Answers (4)

Nathan
Nathan

Reputation: 51

One (proper) way to do this is to set data properties values at the initialization of the viewmodel:

,data: function() {
  return { myVar1: 2
          ,myConst1:WHEEL_DRIVE.ALLROAD
          ,myOtherValue:3.14 };
 } 

but you can access global variables (such as a Map object) using modern browsers a method such as:

 printFromGMap: function(keyName,propName) {
               return (('myMap' in globalThis) 
                   && (globalThis.myMap.has(keyName))
                   && (propName in globalThis.myMap.get(keyName))) 
                  ? `${globalThis.myMap.get(keyName)[propName]}` : '';
            }

since globalThis is now a standard thing (in this code, the question mark is part of the ternary operator and the backticks return a template literal).

Upvotes: 0

Sharhabeel Hamdan
Sharhabeel Hamdan

Reputation: 1549

You can create global variable to be accessed by all components:

Vue.prototype.$variableName = 'My value'

Upvotes: 0

ADM-IT
ADM-IT

Reputation: 4200

You can use computed or even create a custom mixin to get a global value:

<div id="app">
  <p>
    Example 1: {{myGlobalVariable}}
  </p>
  <p>
    Example 2: {{getGlobal('globalVariable')}}
  </p>
</div>
<script>
window.globalVariable = 'I am a global thing';

new Vue({
  el: "#app",
  data: {
  },
  computed: {
        myGlobalVariable: function () {
            return globalVariable;
        },
    },
  methods: {
    // this could be a mixin (see vue docs how to create a global mixin)
    getGlobal(propertyName) {
        if (propertyName) {
            //return this.$el.ownerDocument.defaultView[propertyName];
            //return eval(propertyName); // !!! be careful with that, it opens a hole into security
            return window[propertyName];
        } else {
            return null;
        }
    }
  }
})
</script>

Depending on where you are you can also use:

this[propertyName];
self[propertyName];
window[propertyName];
top[propertyName];
globalThis[propertyName];
eval(propertyName); // !!! be careful with that, it opens a hole into security

If you are looking for a global function:

window[functionName](arg1, arg2);

See the following example https://jsfiddle.net/FairKing/u7y034pf/

Upvotes: 6

Philip Feldmann
Philip Feldmann

Reputation: 8435

As far as I am concerned this is not possible because:

Whenever you are using templates in vue you are also using vue template compiler in one way or another. All template expressions will be turned into render functions, and the source code that the template compiler generates looks like this:

with(this){return _c('div',[_m(0),(message)?_c('p',[_v(_s(message))]):_c('p',[_v("No message.")])])}

Note the with(this) statement at the beginning. Every reference in the remaining function will therefore always be accessed on the instance.

However, even if it was possible this would be an anti pattern:

Vue is relatively opiniated when it comes to state management. Even though you are dealing with a constant here, vue still encourages you to share global state between vue instances using vuex.

You could also just reflect your constant in your vue instance as a an attribute of your components data - I do encourage you to use vuex though if your app grows bigger.

Upvotes: 3

Related Questions