Tips for toggling an Electron.js submenu within a Vue.js Component based on a particular Vuex state

I've searched everywhere for a solution to this issue.

Currently, I am working on a sample vue-vuex-electron app that I have developed. My goal is to dynamically enable or disable certain submenus within the app based on the vuex state 'isLogged' being true or false. While I was successful in implementing this functionality for the nav router-links using v-if, I am facing difficulties with the menu items as I am unsure of how to access the Menu which has already been configured and rendered in the main process.

For instance, within my Home.vue file, I wish to import the Electron Menu of the app and make the following adjustments:

created(){
    if(this.$store.getters.isLogged){
        mainMenu.getMenuItemById('login').enabled = false
        mainMenu.getMenuItemById('logout').enabled = true
        mainMenu.getMenuItemById('currentWeather').enabled = true
    } else{
        mainMenu.getMenuItemById('login').enabled = true
        mainMenu.getMenuItemById('logout').enabled = false
        mainMenu.getMenuItemById('currentWeather').enabled = false
    }
}

However, when attempting to import the Menu, it seems to be undefined rather than the menu that has already been created and set for the app.

Is there a way to access the current Electron Menu from inside a Vue instance in order to modify it?

The entire project can be found here: https://github.com/danielpm1982/open-weather-client

Thank you in advance! :D

Daniel Pinheiro
danielpm1982.com
Brazil

Answer №1

After figuring out a solution on my own since nobody knew the answer, I decided to share it for the benefit of others facing a similar issue.

I encountered difficulty in accessing and managing the Electron Menu within the Vue components in the renderer process. To work around this, I opted to update the menu directly in the main process where all Electron components are easily accessible.

ipcMain.on('setMenuToLoggedInState', (e:Event, isLogged:boolean) => {
  const mainMenu: Menu = Menu.getApplicationMenu() as Menu
  if(isLogged){
    mainMenu.getMenuItemById('login').enabled = false
    mainMenu.getMenuItemById('logout').enabled = true
    mainMenu.getMenuItemById('currentWeather').enabled = true
  } else{
    mainMenu.getMenuItemById('login').enabled = true
    mainMenu.getMenuItemById('logout').enabled = false
    mainMenu.getMenuItemById('currentWeather').enabled = false
  }
});

To notify the main process to update the Menu based on changes to the Vuex 'isLogged' state, I emit an event from the Home.vue component view in the renderer side.

computed: {
  ...mapGetters(['isLogged'])
},
created(){
  if(this.isLogged){
    ipcRenderer.send('setMenuToLoggedInState', true)
  } else{
    ipcRenderer.send('setMenuToLoggedInState', false)
  }
}

In my app, both the Login and Logout routes redirect to the Home View, allowing the Home Vue component to consistently check the 'isLogged' state in the Vuex store upon creation and trigger the main process to update the Menu accordingly.

While this method may not be perfect, it effectively accomplishes the goal.

Although I aimed to minimize the use of ipcMain and ipcRenderer to avoid tightly coupling the Vue components with the Electron API, incorporating them was necessary in this case.

Now, my Menu submenus dynamically reflect the user's login status, and the router-links in the nav bar are generated or removed based on that same state.

A big thank you to everyone who attempted to provide assistance.

You can access the entire project here: https://github.com/danielpm1982/open-weather-client

Daniel Pinheiro
danielpm1982.com
Brazil

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Using VueJS: accessing this.$store within component data property

I am interested in utilizing the data from my Vuex store in both my app and template. My Vuex store: var Vue = require('vue'); var Vuex = require('vuex'); Vue.use(Vuex) let store = new Vuex.Store({ state: { user: ...

Guide on plotting latitude and longitude coordinates on Google Maps with Vue.js through JSON data fetched via AJAX

I have implemented a Vue.js script to fetch JSON data through an AJAX request. However, I am encountering issues with the code. <script> new Vue({ el: '#feed' , data: { details: [], }, mounted() { this.$nextTick(fu ...

When using v-for to render an array list fetched from AsyncData, an error is thrown: The virtual DOM tree rendered on the client-side does not match the one

For my application, I am utilizing Nuxt.js. On one of the pages, I am using AsyncData to fetch an array of data objects from my API asynchronously. These data objects are then rendered in my template using v-for. Everything is functioning properly until I ...

Vue 2 inline event handlers accept two arguments in the template

Is it feasible to retrieve arguments/parameters transmitted to a triggered event within an inline / in-template handler? For example: <component @some-event="someObject.field = $arguments[0]"></component> My goal is to set a value for an obje ...

Determine whether the user has scrolled past a specific threshold

Is there a way to display the button with the id backtotop only when the user has scrolled more than 250 pixels? This is my code: <template> <div> <button v-if="checkScroll" class="goTop" @click="backToT ...

Vue/Antd radio button group styles not being applied properly due to binding issue

I have encountered a peculiar issue while developing a small Vue component. Initially, when I crafted the HTML for a radio button group, everything functioned flawlessly. However, upon transitioning the code to bind to a data source, although it operated ...

The "model" feature appears to be inactive

I discovered a fiddle with a simple radio button functionality that I forked and made some modifications to. The changes worked perfectly, you can check it out in this fiddle: Vue.component('radio-button', { props: ['id', 'v ...

Display a loading spinner when Vue 2 components are loading asynchronously

Seeking a way to asynchronously load a heavy component in Vue and display a loading spinner during the process. Initially tried using loading in data linked to a spinner component with v-if="loading", but ran into issues due to a potential rebinding proble ...

Delivering VueJS Builds via Express.js by leveraging history mode

I am trying to find a way to serve vue js dist/ through express js while using the history router in my vue js app. Here are some of the API calls I need: api/ s-file/sending/:id terms/get/:which I came across a Python solution on Github, but I'm ...

Efficiently monitor several Vue.js properties with a single handler function

Currently I am tasked with monitoring several properties. However, whenever each one of them changes, I must trigger the same function: export default{ // ...... rest of code watch: { propa: function(after,before) { doSomething(after,before ...

Discovering how to access the console once an Electron app has been packaged

Just as the title implies, I have successfully created a node / angular application using electron. The application works perfectly when launched with the electron ./app command. However, after building it (using either electron-packager or electron-builde ...

Implementing Vue.js Lazy-loaded Routes with Dynamic Module Replacement (DMR)

My goal is to implement lazy loading for Vue.js routes using vue-router and Webpack dynamic import statements. Here's how I have set it up: const routes = [ { component: () => import("./components/home.vue"), name: "home", path: "/", ...

Set up global variables for components to access

Currently, I am working on a Laravel 8 project with vue-sweetalert2 integration. My goal is to set up the Toast behavior once and then be able to call it within various components. At the moment, my code looks like this: /js/components/Mypage.vue <scr ...

Is it possible to transmit multiple values that are not contained within a component in the DOM?

I recently started using Vue and attempted to replicate the behavior in the following link: https://jsfiddle.net/kyncgL7w/9/ In my code, I have a simple HTML select tag that displays values from an object called banks. I am using the v-on:change directiv ...

Testing Vue with Jest - Unable to test the window.scrollTo function

Is there a way to improve test coverage for a simple scroll to element function using getBoundingClientRect and window.scrollTo? Currently, the Jest tests only provide 100% branch coverage, with all other areas at 0. Function that needs testing: export de ...

What is the correct method for routing Vue/AJAX requests in Laravel?

I am new to Laravel and creating a web service that can operate without the need for JavaScript, in case it is disabled by the user. However, I believe it would enhance the user experience if certain actions could be performed without having to refresh th ...

Can you explain the significance of the @ symbol in TypeScript/Vue?

I've recently embarked on a new VueJS project and stumbled upon some unfamiliar syntax. I have highlighted the lines with comments below. file(example) : MyModule.vue const storeCompte = namespace("compte") // namespace is based on 'no ...

Repeated parameters when making a second login request with axios and sending data in url-encoded format

Implementing token-based authentication and sending urlencoded data via axios. Passing the user and password to the axios function with all parameters set as per documentation. import axios from 'axios' const params = new URLSearchParams() param ...

Implementing pagination in Nuxt using asyncData

Wondering if it's possible to implement pagination using asyncData in Nuxt? Here is the code snippet I have: <template> <v-container fluid> <v-row> <v-col v-for="sessao in sessoes" :key=" ...

"Implementing a timer feature in a Vuetify stepper component

I recently created a Vue app with a Vuetify stepper. I am trying to modify the steps so that they advance automatically every minute. Below is the code snippet: <template> <v-stepper v-model="e1"> <v-stepper-header> <v-ste ...