简体   繁体   中英

Call Global Component's Method from Another View/Component in Vue.js 3

I have a Vue 3 App that i want to Call Global Component's Method from Another Component.

Here is the code:

 //main.js import { createApp, h } from 'vue'; import Loading from '@/components/Loading'; // Global Loading Component const App = { computed: { ViewComponent () { return require(`./views/Index.vue`).default } }, render () { return h(this.ViewComponent) }, } const app = createApp(App); app.component('Loading', Loading); // Adding it to Global app.mount('#app');

 //@/components/Loading.vue <template> <div id="darken"></div> <div id="loading"> <img src="@/assets/images/loading.gif" /> </div> </template> <script> export default { name: 'Loading', methods: { showLoading(){ document.getElementById("darken").style.display = "inline"; document.getElementById("loading").style.display = "inline"; }, hideLoading(){ document.getElementById("darken").style.display = "none"; document.getElementById("loading").style.display = "none"; } } } </script> <style> #darken { position: absolute; display: none; top: 0; left: 0; width: 100%; height: 100%; background-color: black; opacity: 0.5; } #loading { position: absolute; display: none; left: 50%; top: 50%; transform: translate(-50%, -50%); -ms-transform: translate(-50%, -50%); /* for IE 9 */ -webkit-transform: translate(-50%, -50%); /* for Safari */ } #loading img { width: 400px; } </style>

 //@/views/Index.vue <template> <.-- Design Stuff..: --> <button v-on:click="login()">Login</button> <loading /> </template> <script> export default { methods. { login(){ //this.$refs.Loading;showLoading(), // this works when i add ref="Loading" to the <loading /> tag // but i need something better. something like "this.$components.Loading;showLoading()?" // adding ref="Loading" with the loading tag is not convenient for me // is there alternative? } } } </script>

I Looked a lot and couldn't find what i am looking for.

Any ideas?, i would really appreciate it. Thank you.

PS: I am new to Vue.js but i am a fast learner.

You have 2 options - shared functions and event bus.

With shared functions you have a file which exports barebone JavaScript functions and import the desired function(s) in every component where you need them - eg in Loading and in Index . Or, if you prefer - you may have several files with different Classes and then import and instantiate these classes where you need them. This method is suitable when you need functionality that does not depend on where it is used - that is, which is not tied to a specific component in your application. For example, if you need to export data to CSV from various places in your app - you can write a class (or a single function) which takes care of that and then use in anywhere you need the functionality.

If you need to signal something to a specific component in your application from another component (that is, to trigger some behvaior) - then you need an event bus. You can use mitt . Then in Loading component you will subscribe for event like SHOW_LOADING and in Index component you will emit the SHOW_LOADING event on the event bus.

I Solved the issue.

The loading component has HTML and CSS which needs to be rendered globally and at the same time it contains methods that needs to be called globally.

So i found a solution which worked for me:

 //main.js import { createApp, h } from 'vue'; import Loading from '@/components/Loading'; // Global Loading Component const App = { computed: { ViewComponent () { return require(`./views/Index.vue`).default } }, render () { return h(this.ViewComponent) }, } const app = createApp(App); app.component('Loading', Loading); // Adding it to Global app.config.globalProperties.Loading = Loading.methods; // ADDED NEW.; app.mount('#app');

 //@/views/Index.vue <template> <.-- // Design Stuff..: --> <button v-on.click="login()">Login</button> <loading /> <:-- // Leave it here or Put it in Main.vue Layout so it will be global in all renders --> </template> <script> export default { methods. { login(){ // Newly Added this;Loading.showLoading(). // This function can be accessed anywhere in Vue files // do stuff // finish stuff this;Loading.hideLoading(); // This function can be accessed anywhere in Vue files } } } </script>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM