We are using Vue.js to implement the popup function. The "Click" button in the Vue App will launch the popup correctly, but the following example vueApp.methods.openModal() /// call from outside The popup does not appear when I call from outside, although the function call itself is possible. Why is this? Also, how can I make v-show work properly when calling a method from outside Vue like this?
xxx.html
<div id="app">
<button v-on:click="openModal">Click</button>
<div id="dbg_overlay" v-show="showContent" v-on:click="closeModal">
<div id="content"></div>
<button v-on:click="closeModal">Close</button>
</div>
</div>
xxx.js
const vueApp = {
data() {
return {
showContent: false,
}
},
methods: {
openModal: function() {
this.showContent = true
},
closeModal: function() {
this.showContent = false
}
},
};
Vue.createApp(lessonScheduleEdit).mount("#app");
vueApp.methods.openModal() /// call from outside
vue I am using :
<script src="https://unpkg.com/vue@next"></script>
CodePudding user response:
The easiest way is to use v-if and check if your defined value is equal to true. Like this:
<div id="app">
<button id="show-modal" @click="showModal = true">Show Modal</button>
<modal v-if="showModal" @close="showModal = false">
<!-- Your content in here -->
</modal>
</div>
you can also do showModal = true inside of your methods, just like this:
methods: {
clickModal() { //just renamed in template it's @click="clickModal()"
showModal = true;
}
}
Hopefully this helps you out!
CodePudding user response:
You need the following:
- assign your Vue app to a variable, available anywhere in global scope.
- once you make it available, to call a method defined as
methodNamein itsmethods, you have to call it directly (e.g:myVar.methodName(), not asmyVar.methods.methodName()!!!)
How to make the variable globally available:
The most common method to declare globally available variables would be to use the window object:
window.myVueApp = Vue.createApp(vueApp).mount("#app");
// from anywhere else in the window:
window.myVueApp.openModal();
A more modern way of making a variable globally available is to use window's alias: globalThis:
globalThis.myVueApp = Vue.createApp(vueApp).mount('#app');
// both of these will now work
// because, inside a browser, globalThis === window
window.myVueApp.openModal();
globalThis.myVueApp.openModal();
Note: can I use globalThis?
But, even though window now has a fancy new alias, using it is just as bad (read why below).
Note: Polluting the global scope with variables is generally regarded as bad practice, as it runs the risk of name collisions (when both your code and someone else's, used on same page, accidentally use the same global scope variable names).
Ultimately, this means that, at least in theory, your code is unreliable (it might fail under certain circumstances). Ideally you want to write unbreakable code, which does not interfere with (break) anything else running on same page, at any point.
To minimize this naming collision risk, you could actually place your app inside the Vue namespace, which is already available in global scope, as we already know the Vue namespace does not have a myVueApp property (and the likelihood that anyone else would also use Vue.myVueApp on your page is negligible):
Vue.myVueApp = // ...your app here...
See it working:
const vueApp = {
data() {
return {
showContent: false,
}
},
methods: {
openModal: function() {
this.showContent = true
},
closeModal: function() {
this.showContent = false
}
},
};
Vue.myModeratelyAmazingVueApp = Vue.createApp(vueApp).mount("#app");
<script src="https://unpkg.com/vue@next/dist/vue.global.prod.js"></script>
<div id="app">
<button @click="openModal">Click</button>
<div id="dbg_overlay" v-show="showContent" @click="closeModal">
<div id="content"></div>
<button @click="closeModal">Close</button>
</div>
</div>
<button onclick="Vue.myModeratelyAmazingVueApp.openModal()">external open</button>
