My vue page contains Created, mounted, updated, destroyed hooks. I need to add a condition for page rendering. In my case, in the created hook I make a variable true or false based on a confirm alert and if it true I would like the vue to execute other lifecycle hooks else route to a different page.
Is it possible with vue to do this, if yes, how?
In your created hook if this value is false and you want to redirect to different page you can use location API.
//...
created: function () {
// your code
window.location.replace("https://google.com"); // this will redirect you to another page
}
//...
Related
I can't find the solution to this anywhere.
I have this sample vue-vuex-electron app that I've created and I want to enable / disable some submenus of the app according to whether the vuex state 'isLogged' is true or false. I managed to apply that to the nav router-links (using v-if), but not yet to the menu items... 'cause I don't know how to access the actual Menu (already set and rendered at the main process).
For example, at my Home.vue, I'd like to import the Electron.Menu of the app and set the following:
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
}
}
But, when I try to import the Menu it's returned as undefined, not the menu already created and set to the app.
HOW CAN I HAVE ACCESS TO THE ACTUAL ELECTRON MENU FROM INSIDE A VUE INSTANCE IN ORDER TO CHANGE IT ?
The whole project is here:
https://github.com/danielpm1982/open-weather-client
Thanks in advance ! :D
Daniel Pinheirodanielpm1982.comBrazil
OK, nobody knew this one, so I managed to work around it myself... and I'm sharing the solution to help others.
I actually could not find a way to get or manage the Electron Menu at the renderer process, from within the Vue components, so I let it to be updated at the main process itself, where I have access to all Electron components easily.
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
}
});
Then, at the renderer side, or at the Home.vue component view, I simply emmit an event to the main process to notify it when the Vuex 'isLogged' state changes, that is, when I want it to update the Menu.
computed: {
...mapGetters(['isLogged'])
},
created(){
if(this.isLogged){
ipcRenderer.send('setMenuToLoggedInState', true)
} else{
ipcRenderer.send('setMenuToLoggedInState', false)
}
}
As, in the case of this app, both the Login as the Logout routes redirect to the Home View, the Home Vue component will always be able to check the 'isLogged' state at the Vuex store, on its creation, and notify the main process to update the Menu or subMenus according to that state.
I don't know if there's a better way for this, but it works this way.
I was avoiding to use ipcMain and ipcRenderer as much as I could, for not coupling the Vue components code with the Electron API, but in this case I had to use it.
Now, my Menu submenus are activated and deactivated according to the user login state, as well as the router-links of the nav bar are generated or not according to that same state.
Thanks to all those who might have tried to answer that.
The whole project is here: https://github.com/danielpm1982/open-weather-client
Daniel Pinheiro
danielpm1982.com
Brazil
I have some v-if props and currently to show divs with #click="tada = !tada". Instead, I would like the same divs that I'm currently triggering with the #click, to appear when the page finishes loading and occur only once.
I have tried onload, load and other things to know avail. Thanks for any help
EDIT:
I suspected it had to do with mounted but wasn't sure, so thank you for the hint.
Answer:
mounted: function () {
this.tada = true
},
You should use the mounted lifecycle hook in your main vue instance. This function is called when the component is rendered to the document for the first time. You can read more here.
I have a call in my created method which has an await.
I want to know that the results of that call are loaded so that i can conditionally show/hide things in the DOM.
Right now it looks like the DOM is being rendered before that method has completed. But I though that methods in created were called before the DOM rendered?
You're correct in assuming that the created hook runs before the component mounts. However, the lifecycle hooks are not waiting for async calls to complete. If you want to wait for that call to be completed and data to load, you can do so by using a Boolean that you set to true when your data has loaded.
Your template:
<div v-if='dataLoaded'>Now you can see me.</div>
in your vue instace
export default {
data () {
return {
dataLoaded: false
}
},
created () {
loadMyData().then(data => {
// do awesome things with data
this.dataLoaded = true
})
}
}
This way you can keep your content hidden until that call has resolved. Take care with the context when you handle the ajax response. You will want to keep this as a reference to the original vue instance, so that you can set your data correctly. Arrow functions work well for that.
Hot reloading works fine with class components but when it comes to function components with hooks such as useState, hot reloading resets its value.
Hooks rely on the calling order to make sense.
https://reactjs.org/docs/hooks-faq.html
There is an internal list of “memory cells” associated with each component. They’re just JavaScript objects where we can put some data. When you call a Hook like useState(), it reads the current cell (or initializes it during the first render), and then moves the pointer to the next one. This is how multiple useState() calls each get independent local state.
From https://github.com/gaearon/react-hot-loader
Hook support
Hooks would be auto updated on HMR if they should be. There is only one condition for it - a non zero dependencies list.
❄️ useState(initialState); // will never updated (preserve state)
❄️ useEffect(effect); // no need to update, updated on every render
❄️ useEffect(effect, []); // "on mount" hook. "Not changing the past"
🔥 useEffect(effect, [anyDep]); // would be updated
🔥 useEffect(effect, ["hot"]); // the simplest way to make hook reloadable
To disable hooks reloading - set configuration option:
import { setConfig } from 'react-hot-loader';
setConfig({
reloadHooks: false,
});
I have a component that displays Users in a ListView which needs to make a fetch call before it renders.
I navigate to this component using:
this.props.navigator.resetTo({ id: 'ListUsers', getusers: true });
In the ListUsers component I have componentWillReceiveProps so that I can make the fetch call before render.
However the method is never called.
Further from ListUsers I can navigate to the AddUser component.
From here either a new user is added or the user can Cancel.
If new user is added, I navigate back to the ListUsers component using:
this.props.navigator.resetTo({ id: 'ListUsers', getusers: true });
At this point componentWillReceiveProps is called.
if user cancelled then I navigate back to the ListUsers component using:
this.props.navigator.pop();
Can anyone help to see what I am doing wrong?
You perfectly described what the documentation says will happen when using componentWillReceiveProps
From the docs:
componentWillReceiveProps
Invoked when a component is receiving new props. This method is not
called for the initial render.
In your scenario, is there any reason why you can't use componentWillMount to make the fetch call? componentWillMount is called right before the component is rendered, and it is the first point you can call setState.
If the problem is you need to guarantee that render only shows certain data before the fetch is completed, there are some strategies to do that, but the simplest way may be to simply set a flag to false in your state in the constructor (if you are developing using ES6 methodology), and flip it to true after the fetch is complete. An if statement in your render method would round out this strategy.
If you want me to put together a more comprehensive example, I can do so.