Vue-Router with dynamically generated aliases (also SSR) - vue.js

Our business logic allows different types of profile pages (user profiles, company profiles, etc - each with its own template), but the URLs do not discriminate between the types of profiles. All URLs are of the format:
mysite.com/{{ profile-vanity-alias }}
How would a vue-router configuration determine which component to render? e.g.
mysite.com/zuckerberg should render a user profile page
mysite.com/facebook should render a company profile page
mysite.com/jeffbezos does not exist so it should render a 404
mysite.com/companies/usa should render a different page with a list of companies from USA (/companies/:country? is a known route that can be hardcoded)
Furthermore, we're also considering to use vue-ssr (for SEO); I never really used SSR, so that's something where I wouldn't know where to start - a few pointers would be extremely helpful!
Thanks!

you can use switch logic to determine which component you need to load, then dynamically load the component.
<component v-bind:is="component" />
Maybe you can look into detail with this article. https://blog.logrocket.com/how-to-make-your-components-dynamic-in-vue-js/

The route path is obviously something like /:profile. I would have a generic parent component that responds to that route and loads the corresponding profile object (from the API, etc) and, based on some flag or other criteria, it displays the profile component of the person or the one of the company - and here a dynamic component might play a role.
As a short sketch, in the parent component I would have:
<div>
<user-profile v-if="currentObject.isUser" :id="currentObject.id" />
<company-profile v-if="currentObject.isCompany" :id="currentObject.id" />
</div>

Related

NuxtChild not showing child component

On _collection.vue I have something like
<div>
This is a collection
<NuxtChild />
</div>
And inside of category > index.vue I have content like
<div>
This is a Bicycle Page
</div>
If I go to http://localhost:3000/collection/bicycle
It will only show This is a Bicycle page but it will not show the parent layout.
What am I doing wrong?
Isn't _collection.vue the parent of anything inside of the _category folder? Shouldn't everything _collection.vue show in addition to the child components?
Here _category and _collection are at the same level, so it's basically one of them.
You cannot have 2 variables at the same time, it's like asking: "what is my variable: X or Y?".
You can have only 1 dynamic page, especially at the same level. If you want to have /collection/bicycle, then collection directory and _type.vue (for bicycle) inside of it should be enough.
I think you have mixed up the concepts of pages, components and layouts here.
If you are trying to set up a layout that is applied to each page in pages/collection, you could make use of an actual layout.
If you are trying to display a particular piece of content on multiple pages, you should use components.
Further information around nested route handling.
Just change a _collection.vue to index.vue If you want to have collection path as dynamic value, change folder name to _collection. And as kissu wrote you in a comment, you have two routes at the same level, so it reads just one. All you need to do is change _collection.vue file name if you don't need a flexible route.

How to use value selected by user on log in page in VueJS?

The web app I'm working on has a log in page where it asks users to select which site they wish to use, this site selection is done as so:
<v-select v-if="step > 0" v-model="userId" label="Select Account" :items="accounts" item-text="owner.name" item-value="id" :rules="[rules.isRequired]" :disabled="step > 1" /> (The site names provided in the dropdown are saved in a mysql table called owners).
The task at hand is to make the name of the site they chose display on every page. To do this, I am aiming to put the name in the nav bar at the top, as so:
<v-toolbar-title class="d-flex text-center"> NAME_HERE </v-toolbar-title>
I currently cannot figure out how I would bring the site name that they chose and display it how I wish to do so, and would really appreciate the help.
sidenote: the login code is from a login.vue file and the name display part is in AppBar.vue.
There are multiple ways to achieve your goal.
Pass value from the root component
You can store selected values from a user by using callback in login.vue. Callback user should be called when a user changes the site name, then pass values back to the main component (in this case might be App.vue).
But, This method is really ugly if you have 5 nested vue components, so you have to pass a callback function down through 5 components. So let talk about a next solution.
Vuex, the global store
You can store values from anywhere by anyone inside a state store. There is a library named Vuex. It allows you to save values that any component can access.
In this case, you can update the site name via login.vue then AppBar.vue access it on its own.
Read more about it here. https://vuex.vuejs.org/
However, Vuex kinda makes your app more complicated. Use it when there are no other ways you can think of.

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.

Vue.js Vue3 different Templating with for sub components

I have a Vue 3 project,
Most of my Components use the Template in App.vue (My understanding goes that this is Similar to a "Master Page in .net core with the completeness inheriting the style and layout from the App.vue. In my case, the app.vue will have the dashboard layout (top and sides) and then I will load the restricted components in the content section.
However, I cannot seem to figure out how to make public-facing pages, such as login and register not reference the Dashboard template at all as they are not logged in, but still allow some Vue functionality. Post for login, errors returned, etc. How can I split them or have multiple Master App.vue templates for different users, based on their role or logged-in status.
your help is greatly appricated.
In App.vue you can use vue js built in component tag to render dynamic layouts
<component :is="activeLayout"></component>
you can bind it to a computed property and return the appropriate component to bind for different scenarios

Is it a bad practice to have 2 components with the same name if they're in different folders?

Lets say I have a website where I sell some sort of products. I'd have a Product.vue component which will be used to render all the products the user would see on the home screen.
I'd also need a second component that will be used to render the products on the admin panel, where the admin will be able to edit/delete.
Obviously both components will render a product, but they'll look different, have different functionality so I assume I can't make an all-mighty universal component for that, so I'd need 2 different components.
Now I'm really confused how to name my components. Currently I have the following folder structure:
Components
---Admin
------Product.vue
---Product.vue
So in the components folder I have a Product.vue and the Admin folder, which contains the admin Product.vue. I'm wondering if having 2 components with the same name in different folder is a bad practice?
The second alternative is calling the admin product AdminProduct.vue
Two components with the same name in the single app is never a good idea from maintainer point of view.
Lot of useful info can be gained from Vue Style Guide
Multi-word component names
Component names should always be multi-word, except for root App components, and built-in components provided by Vue, such as <transition> or <component>.
This prevents conflicts with existing and future HTML elements, since all HTML elements are a single word.
Tightly coupled component names
Child components that are tightly coupled with their parent should include the parent component name as a prefix. If a component only makes sense in the context of a single parent component, that relationship should be evident in its name.
So AdminProduct.vue is fine...
And instead of Product.vue it should be a ProductView.vue
Vue has an object hierarchy and beyond that it can render even multiple instances of the same component. So object-wise you're good.
Regarding the file names, I don't see big risks in it because one of the Product.vue files is clearly in the Admin folder and the other is not. However if this is a project that will be worked on by multiple developers, it might be wiser to name them differently. Not because git can't deal with directory structures, but because humans can make errors. At least I do it all the time.