open route in a sidepage using vuejs - vue.js

I'm building a back office using Quasar. I would like to be able to open routes in what I would call a sidepage (for the lack of a better better word... maybe you have one?).
Opening a route in this sidepage would render the component requested without decoration (like menus).
This route could potentially however be opened directly in a new window (not in a sidepage) with decoration.
From this sidepage, I would like to be able to open another sidepage, and so on.
This is basically what I'd like to do (https://tagmanager.google.com/) :
I've literally no clue how to do that. I'm trying to build a component that would take a route, create a sidepage, size it correctly (as you can see the second sidepage is smaller than the first one) )and open the route in it but I fail to do so.
Any clue where to start or any idea on a component that would do that already ? I haven't found anything yet.

You could search for your component using the path in the router options.
const route = this.$router.options.routes.find(
(route) => !!route?.path?.includes("route/to/display")
)
this.component = route?.component;
And then display it using component tag.
<component :is="component" />

Related

Is it possible to use NuxtLink to a Vue "component" in the components directory vs. a "page" route

I'm trying to create a form that I want to use modularly by linking to it from multiple page templates. Using just the straight vue-cli I would simply create a route to the file that has the form defined that I store in the "components" directory and then wrap a button linking to the form in a <router-link to="componentFormName"><btn></btn></router-link>. I'm having some difficulty determining how to do the equivalent in Nuxt. Any insights would be greatly appreciated. It seems the <NuxtLink></NuxtLink> only works with Vue files in the "Pages" directory.
You probably want to use dynamic components here: https://v2.vuejs.org/v2/guide/components-dynamic-async.html#keep-alive-with-Dynamic-Components
With something like this
<component :is="currentTabComponent"></component>
With currentTabComponent being one of the component to mount. You can mount a component depending of the current route with a relation between the URL and the component name too.
Also, Vue does not have any knowledge of "route", and everything is a component. Nothing really changes with a page because it is also a component at the end of the day. Or you could write one inside of it.
Maybe an example of your use-case would be helpful here.

How do i get the active route the correct way?

I'm using the typical Vue Router configuration as shown in their guide. What i want is to show the name of the shown route, outside of the router-view. So i would need to ask the router which route is active.
I've found in the router API that it has a currentRoute property, which i was hoping would give me the active route, and i would read its name, and then i'm fine from there.
To test this, i imported the router like so:
import router from '#/router.js';
Then tried to read the name of the active route:
data: function(){
return {
test: router.currentRoute.name
}
}
And displaying it with {{ test }}.
It seems like it's sort of doing what i wanted it to, but it's super inconsistent and unreliable. I don't get any errors anywhere, and the route name does not show up, and seemingly does not work. But then (sometimes) if i change something in my component's template, like delete an element, or add an element, and Vue hot-reloads my app, the route name appears and continues working. From there, if i refresh, it won't appear again.
What am i doing wrong, and what is the correct way of reading the active route name?
Subquestion
Would it be a good idea to use router.beforeEach for this? Because that seems to work correctly, but it seems like a wrong approach for this...
A route object represents the state of the current active route. It
contains parsed information of the current URL and the route records
matched by the URL.
Reference.
You can access current route object through this.$route;.

Initialize dynamic Component in Code using Vue.js

I am currently developing a web application that is used to display elements for events on a map provided by HERE Maps. I am using Vue.
I have some components, but the relevant component is the component HereMaps.vue which initializes the map using the HERE Maps Api.
The HERE Maps Api provides the possibility to place so called InfoBubbles on the map showing additional information. These InfoBubbles can be provided some HTML-code in order to customize their appearance.
Please refer to the documentation for additional information
Following the documentation the code looks something like this:
let bubble = new H.ui.InfoBubble(marker.getPosition(), {
content: "<div class='someClass'>Some Content</div>"
});
this.ui.addBubble(bubble)
This is happening after mount in the "mounted" method from Vue in the "HereMaps" component.
The Bubbles are added in a "closed" (hidden) form and dynamically "opened" to reveal their content when the corresponding marker icon on the map is clicked. Therefore the HTML-code is present on the DOM after the component is mounted and is not removed at a later stage.
Now instead of supplying custom code within each bubble added to the UI i want to just add a component like this:
let bubble = new H.ui.InfoBubble(marker.getPosition(), {
content: "<myDynamicComponent></myDynamicComponent>"
});
this.ui.addBubble(bubble)
It does not matter to me wether the component is initialized using props or if it is conditionally rendered depending on the state of a global variable. I just want to be able to use the "myDynamicComponent" in order to customize the appearance in a different file. Otherwise the design process gets very messy.
As far as i know this is not possible or at least i was not able to get it work. This is probably due to the fact that the "myDynamicComponent" is not used within the "template" of the "HereMaps" component und thus Vue does not know that it needs to render something here after the directive is added to the DOM in the "mounted" method.
This is what the InfoBubble looks using normal HTML as an argument:
This is what the InfoBubble looks using the component as an argument:
It appears to just be empty. No content of the "myDynamicComponent" is shown.
Does anyone have any idea how i could solve this problem.
Thank You.
Answer is a bit complicated and I bet you wouldn't like it:)
content param can accept String or Node value. So you can make new Vue with rendered your component and pass root element as content param.
BTW, Vue does not work as you think, <myDynamicComponent></myDynamicComponent> bindings, etc exists in HTML only in compile time. After that all custom elements(components) are compiled to render functions. So you can't use your components in that way.
Give us fiddle with your problem, so we can provide working example:)

what is the best way to use vue, vue-router to make a dashboard with keep-alive?

I'm using vue2, vue-router with keep-alive to develop a dashboard. What I want to achieve is following:
page should re-fetch when login -> logout -> login other account
(use beforeRouterEnter, beforeRouterLeave to re-fetch !? or use condition to keep alive component or not !?)
but vue-router can't use vue data to check page should keep alive or not...
in HTML template, it will render and render. If there has some vuex data show directly in HTML, it will error with not have the object inside object yet ex:
user: {
plan: {
xxx: ''
}
}
sure I can give vuex data all of property init data. It can avoid this thing happen, but if the page with keep alive, it still happens...
also, I can write many v-if in the template, but I think it's not a good idea to put v-if all around the template to make sure data exist..ex:
v-if="user.plan && user.plan.xxx"
or add v-if in component root template, is that a good idea !?
use beforeMount without keeping alive, there is no problem but it's not a good user experience dashboard (when you change page, data disappear or you have already load page data but load again)
Is there anyone who really use Vue 2 and it's relative library (vuex, vue-router) to develop can tell me how you develop your SPA project !?

Aurelia top level component without routing

Is it possible to add an Aurelia top level component without the router?
The goal is to create a component without the router since my application doesn't need any url based navigation.
From what I can tell Aurelia seems to take you down a path where components are instantiated via routing based on how the component is registered with the router.
Instead I would like to just add markup for the top level component on the main index.html page:
<my-component bind.current="'123456'"></my-component>
I would like define components without a router and only use the templating and data binding capabilities of Aurelia.
Is that possible?
Tried this in index.html (inside the body tag of the default project)
<require from='./dist/my-component'></require>
<my-component></my-component>
But it does not seem to pick it up. Ideally I would like to just define it in markup on a page served from the server since it would enable me to sett attributes dynamically on the elements
<my-component current.bind={{someServerGeneratedId}}></my-component>
In the above I would use a templating framework like mustache to dynamically render the Aurelia when the page is served from the server.
I could wrap the component in another "landing" component, but that makes it hard to benefit from setting things up with server generated bindings.
UPDATE:
Per Rob's response: https://github.com/aurelia/framework/issues/175#issuecomment-126965417
- He is expecting to add the ability to add a root component to the landing page in a future release. I understand there are ways to not use the router, but it still depends on pulling in a partial view during bootstrapping of the application. This does not use the router directly, but conceptually this is really just an implied/convention based client side nav. In the end there is a client side request to pull in the view, which means I can't generate the html dynamically from the initial server response.
Yes you can do this very easily without the router. Just remove the router configuration from your app.js and in app.html remove the router code there as well.
I think the issue you are running in to is that you are specifying the dist folder again in your index.html. You should just reference it like this -
<require from="my-component"></require>
<my-component current.bind="someServerGeneratedId"></my-component>
This will bind up correctly.
I guess you're missunderstanding the route concept here.
At the time of writing, Aurelia's index.html page is your initial page where you put your "loading" stuff and where Aurelia bootstraps the entire app.
So, you can't put a custom component directly on it, but that should not be a problem.
If you don't change any configuration on Aurelia, it will look for your app.html to bootstrap your app, and there you can have anything you want (routes or not, doesn't matter). So, you should put your component there, beside the other tags/components/etc you need.
I've made a plunker without any routing and with a custom component in the app.html, and something simulating what you need.
<template>
<require from='./my-component'></require>
<my-component current.bind="serverGeneratedID"></my-component>
</template>
http://plnkr.co/edit/mLb8Ym638b4V2e9LDp0A?p=preview
If you need anything else, comment here and I'll try to go further.