Here is my base App.vue
that holds the router-view
:
<template>
<div>
<Navbar/>
<div class="container-fluid">
<router-view></router-view>
</div>
</div>
</template>
<script>
import Navbar from './ponents/Navbar.vue';
export default {
name: 'App',
ponents: {
Navbar
}
}
</script>
In the Navbar.vue
, I have a method:
methods: {
getLoggedStatus(){
console.log('asdasd')
}
}
Lastly, I have a Login.vue
that is loaded there on the router-view
. I wanna acess the getLoggedStatus()
from the Navbar.vue
within Login.vue
. How can I achieve this?
I tried putting a ref to the Navbar
tag in App.vue
:
<Navbar ref="navvy"/>
And calling in on the Login.vue
with:
this.$refs.navvy.getLoggedStatus()
But it doesn't work.
Here is my base App.vue
that holds the router-view
:
<template>
<div>
<Navbar/>
<div class="container-fluid">
<router-view></router-view>
</div>
</div>
</template>
<script>
import Navbar from './ponents/Navbar.vue';
export default {
name: 'App',
ponents: {
Navbar
}
}
</script>
In the Navbar.vue
, I have a method:
methods: {
getLoggedStatus(){
console.log('asdasd')
}
}
Lastly, I have a Login.vue
that is loaded there on the router-view
. I wanna acess the getLoggedStatus()
from the Navbar.vue
within Login.vue
. How can I achieve this?
I tried putting a ref to the Navbar
tag in App.vue
:
<Navbar ref="navvy"/>
And calling in on the Login.vue
with:
this.$refs.navvy.getLoggedStatus()
But it doesn't work.
Share Improve this question asked Nov 5, 2019 at 11:22 Dran DevDran Dev 5197 silver badges21 bronze badges 2-
Because
refs
is available in App.vue context i.e.this
, not in Login.vue. IMHO I don't think it's a good strategy to get loggedStatus like this. – haMzox Commented Nov 5, 2019 at 11:40 - @hamzox any suggestions? :/ – Dran Dev Commented Nov 5, 2019 at 11:51
2 Answers
Reset to default 5A ref only works on children. You're rendering <Navbar>
within app, so you cannot call that ref from login. You can only access this.$refs.navvy
from App.vue
.
There are several solutions for your problem.
Emit an event from Login to App, so App calls the method from a ref.
You can set a listener in the router-view, as:
<router-view @loggedStatus="callLoggedStatus" />
In your login, when you would want to call the navbar getLoggedStatus
, you would instead emit that event:
this.$emit('loggedStatus')
And then in App.vue, you would defined a callLoggedStatus
methods that call the ref:
callLoggedStatus() {
this.$refs.navvy.getLoggedStatus();
}
Given that you add the ref to the <Navbar>
ponent in the APP template.
This solution is arguably the most similar to your proposed code, but I think it is a mess and you should avoid it, since you can end up listening to a lot of different events in your App.vue.
Use Vuex
I don't exactly know what getLoggedStatus
does, but if you want to change how your navbar behaves when the user is logged in, you should probably setup a vuex store, so you register there wether the user is logged or not. Then in your navbar ponent you render things conditionally depending upon the user is logged or not.
@Lana's answer follows this idea, and is probably the closest to the official way to thins in Vue.
Use an event emitter
If you want to directly municate between ponents that are not in the same family, I think an event emitter is a reasonable choice. You could setup an application wide event emitter after creating the app:
const app = new Vue({...});
window.emitter = new Vue();
(in the example we use a new Vue as event emitter. There is also the 'events' module which allow to use a EventEmitter)
And then any ponent can use it to send messages, so Login could do:
window.emitter.$emit('user-logged', myCustomPayload);
And Navbar on the other hand could do:
window.emitter.$on('user-logged', function() {
this.getLoggedStatus();
})
This last option is not well considered in the Vue munity -Vuex is preferred- but for small applications I think it is the simplest.
The dirty hack
You can always export your ponent to window. In the Navbar created
hook you could do:
created() {
window.Navbar = this;
}
And then in Login.vue you could, at any time:
window.Navbar.getLoggedStatus()
And it will work. However, this is surely an anti pattern and can cause a lot of harm to your project maintainability if you start doing this with several ponents.
It looks like getLoggedStatus
returns some global state of the app. Use Vuex for managing these global variables.
Create a store like this:
// Make sure to call Vue.use(Vuex) first if using a module system
const store = new Vuex.Store({
state: {
loggedStatus: 0
},
getters: {
getLoggedStatus: state => {
// to pute derived state based on store state
return state.loggedStatus
}
}
})
Use store.state.loggedStatus
in any Vue-ponent to access the global state or use getters like store.getters.getLoggedStatus
if you need to pute derived state based on store state.
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745157287a4614200.html
评论列表(0条)