2

I am using : Global data with VueJs 2 as my starting point as I only want to R/W one variable.

I have added an @click event to the existing code to modify the variable, but I get an "Uncaught ReferenceError: $myGlobalStuff is not defined".

Can anyone see what I am doing wrong:

HTML:

 <div id="app2">
  {{$myGlobalStuff.message}}
  <my-fancy-component></my-fancy-component>
  <button @click="updateGlobal">Update Global</button>
</div>

VueJS:

var shared = { message: "my global message" }

shared.install = function(){
  Object.defineProperty(Vue.prototype, '$myGlobalStuff', {
    get () { return shared }
  })
}
Vue.use(shared);

Vue.component("my-fancy-component",{
  template: "<div>My Fancy Stuff: {{$myGlobalStuff.message}}</div>"
})
new Vue({
  el: "#app2",
  mounted(){
    console.log(this.$store)
  },
  methods: {
    updateGlobal: function() {
      $myGlobalStuff.message = "Done it!"
      return
    }
  }
})

As you can see I am adding very little to the existing code, and that works well.

Any help on what I am overlooking would be appreciated.

Tony Sherman
  • 285
  • 1
  • 6
  • 18

1 Answers1

6

Well first, the error you are getting is because you do not reference $myGlobalStuff using this. Change to this

this.$myGlobalStuff.message = "Done it!"

And you won't get the error anymore.

But I suspect it won't work the way you are expecting it to, in that, it won't be reactive. I think what you want is for the message to be updated on the page, and that is not really the intent of this code. The original point was just to supply some global values to each Vue or component.

To make it reactive we can add one change.

var shared = new Vue({data:{ message: "my global message" }})

Once you do that, message will be a reactive value.

console.clear()

var shared = new Vue({data:{ message: "my global message" }})

shared.install = function(){
  Object.defineProperty(Vue.prototype, '$myGlobalStuff', {
    get () { return shared }
  })
}
Vue.use(shared);

Vue.component("my-fancy-component",{
  template: "<div>My Fancy Stuff: {{$myGlobalStuff.message}}</div>"
})
new Vue({
  el: "#app2",
  mounted(){
    console.log(this.$store)
  },
  methods: {
    updateGlobal: function() {
      this.$myGlobalStuff.message = "Done it!"
      return
    }
  }
})
<script src="https://unpkg.com/vue@2.2.6/dist/vue.js"></script>
 <div id="app2">
  {{$myGlobalStuff.message}}
  <my-fancy-component></my-fancy-component>
  <button @click="updateGlobal">Update Global</button>
</div>

This is a very naive implementation of how Vuex works. The further you progress down this path, the more features of Vuex you end up implementing.

Bert
  • 80,741
  • 17
  • 199
  • 164
  • 1
    Thanks Bert, you must have cried to see your code, screwed up so easily. OK Understood, but will the variable change, I really do not need reactive, just a global store. I only used the event to prove my change happened. – Tony Sherman Jul 14 '17 at 20:40
  • @TonySherman It did update the variable, however the variable is not *reactive*. See the note I added. To make it reactive we need to do additional work. – Bert Jul 14 '17 at 20:41
  • @TonySherman I added a little code that will make it *reactive* but note the very last sentence. The more you end up relying on this store, the more you should consider using Vuex. – Bert Jul 14 '17 at 20:47
  • @TonySherman Doh, I didn't see your comment was edited. Yes, the value is updated, without the additional work. [This codepen](https://codepen.io/Kradek/pen/eRXrPK?editors=1010) shows that the global object changes after you set it via `$myGlobalStuff`. – Bert Jul 14 '17 at 20:51