I'm working on an app using Vue.js and I came across the following challenge:

The app has a pretty basic layout: a header, a main view and a navigation section at the bottom. Depending on the page the user is currently on I want to show a main action in the header. See the following wireframes:

App wireframe of view 1App wireframe of view 2

My question now is: is there a way to "inject" the template and code into the header? Because ideally I would like to have the logic and the appearance (like an icon with label) in the corresponding component and not in the header, because it isn't aware of the current view.

The header and the main view of the components have no parent/child relation. The basic Vue.js template looks like this:

<div class="app-content">
    <TheTopBar/>
    <main>
        <router-view></router-view>
    </main>
    <TheNavigationBar/>
</div>
2

There are 2 answers

1
Michal Levý On BEST ANSWER

I see two ways to do it...

  1. Add default slot into TheTopBar template at the place you wanna see your actions
  2. Remove TheTopBar component from your top-level component, place it inside your "main view" components templates (each of them) and define content of the slot there (actions)

Other way could be using Vue router's Named Views but that would require you to create separate "actions" component for each corresponding "main view" component

Edit

Actually there is other way. portal-vue allows exactly what you want....

2
T. Short On

The short answer is no, you cannot inject code from one component to another. You will have to have the template logic inside the header component.

However, there are a couple of things you can do.

  1. Inside the header component you can check what the current path is with this.$route.path. And based on that display the action item. (if you are using a router)
  2. Use a vuex store to track what the action item in the header should be. You could have the main component set the store value and header can then read it and act accordingly

I hope this answers your question.