bakis
bakis

Reputation: 675

Best approach to change variable value outside of Vue component

I am searching for the best approach to change Vue variable value outside of component. I'm using Vue webpack as well.

I have created a project using vue webpack. Inside its default App.vue file, I have a variable. For example, let's take showModal and its default value is false. Then I built it in a single javascript file.

<button>Register</button> {{-- event button --}}
<div id="guest"></div> {{-- Here I'm rendering my template --}}

<script src="{{ asset('js/vue-js/guest.js') }}"></script> {{-- builded Javascript file --}}

And the problem is that I want to change my showModal variable to true, but the event button it is not on my component template.

What is the best approach to accomplish this?

Upvotes: 5

Views: 19758

Answers (3)

li x
li x

Reputation: 4051

Firstly, best approach wise it's prevalent to think about the relationships between your existing components and their relationships. So for instance if the information your trying to pass will be used in a direct sibling or further down the chain you could choose props.

If your dealing with two components that share no direct relationship other than there current state you will need to extrapolate to either using the repository pattern or Vuex (flux like state management library) where we can then pass a reference to state or into properties in the repository pattern.

FooRepository.js

export default class FooRepository {
  SomeRef
  ManyRef = []

  addRef(name) {
    this.someRef = name;
  }

  addRefs(names){
    this.ManyRef.push(names);
  }

}

The above can be instantiated in your App Layer and shared between your components using an instance property https://v2.vuejs.org/v2/cookbook/adding-instance-properties.html

Dependent on your apps size it might be time to include Vuex where we can save a reference directly into our state and use it in a simmilar manner as the repo pattern. Though as it's an officially supported package the setup and use is much simpler:

const store = new Vuex.Store({
  state: {
    ref: null
  },
  mutations: {
    saveRef (state, compRef) {
      state.ref = compRef
    }
  }
})

This is a very basic store that shows how we could save a reference into it, we can then access this reference in our components once we've registered the store inside main. This can be done using this.$store.state.ref. These two approaches are considered the best approach over simple simple props and or something like the event emitter for components that share no direct relationship.

Upvotes: 4

pr0p
pr0p

Reputation: 2358

Create a new Vue instance just for emitting, call it global event manager.

global.event = new Vue()

when you want to emit an event ( like modal )

global.event.$emit('close-modal', (optional msg))

when you want to close modal :

// In your component

created(){
    var App = this;
    global.event.$on('close-modal', (optional msg)=>{
         this.showModal = false;
    })
}

Similarly do it for opening the modal. If you are using the vue CDN (normal js file of vue), instead of global.event use window.event while creating and only event while using. In browser if a variable which is undeclared is used then it refers to the window object.

Upvotes: 1

Thomas
Thomas

Reputation: 2536

If you want to access a vue component outside of vue you could register it to the window object and access it then from anywhere.

window.myVueComponent = new Vue({
  router,
  store,
  render: h => h(App)
}).$mount('#app')

Now you can access it from anywhere else with

window.myVueComponent.myValue = 123

But this "style" is called global namespace pollution for reasons. ;)

I think it is better to extend your vue app so that the button is also within the vue-handled components.

Upvotes: 5

Related Questions