Using multiple pages (components) dynamically in Vue js - javascript

I am using Laravel Nova custom tool which uses vue js for custom functionalities.
There is a tool.vue file inside of the component after creation, that everything handles there. The thing is I would like to have different templates (vue files) and render them whenever they are needed.
In this case my main tool.vue is a search with dropdowns which I completely implemented. But I want to render the list of the results from a different vue file after clicking on a button. (of course the other vue file will consist of a table or something to show the data).
The question is how to handle this with vue js and how can I change between components ? and how can I pass paramters/data from the main vue file into the result page so I can do ajax requests or etc.

You might want to use a good router for handling the pages dynamically and in SPA format. Seems like Laravel Nova is using vue-router.
It is installed under the custom component as you create it and if you want to use other vue files or switch between them, you need to add your route under nova-components\[your-component-name]\resources\js\tool.js file by adding an object into the array of routes in this format:
{
name: '[route-name]',
path: '/[route-path]/:[sent-prop-name]',
component: require('./components/[your-vue-file]'),
props: route => {
return {
[sent-prop-name]: route.params.[sent-prop-name]
}
}
},
After adding the router to this file you can always use <router-link></router-link> component inside your Vue files to redirect to whatever route you desire (you can also send data to the route as props). The main format of it is like this:
<router-link
class="btn btn-default btn-primary"
target="_blank"
:to="{
name: '[destination-route-name]',
params: {
[your-data-name]: [your-data-value]
}
}"
:title="__('[your-title]')"
>
Submit
</router-link>
P.S: Of course you can omit props and params from both if you don't intend to send and receive any data to the file.
P.S: You can always take look at vue-router documentation here for more features.

Related

Vue dynamic route prerender

I'm working on a Vue project and I've got an issue.
I would like to prerender some dynamic routes when I am in a particular route.
In my project, I have a /works route which displays a list of several items. Each item
has a router-link that sends to his /work/workID route and renders the workpage component. As this is a dynamic route, Vue does not prerender these routes and each time I load, I have a 500ms delay of images loaded.
My images url are store in Vuex and the images are upload in a public google drive folder.
I think that I should use something like that :
let matched = router.resolve(work/workID).resolved.matched;
let route = matched[matched.length -1];
route.components.default.render;
But my images are still loading on mounted.
Hope someone know the issue ;)
Found a way to resolve it.
I declare my dynamic route props to true, then render and hide all the dynamic components in my works pages. That work perfectly.
I can't find the way to pass route params or even props to a component with the router.resolve(path) method. Someone would know how to do ?

Laravel & React | How to implement one view per one component?

I'm trying to integrate Laravel with React that has multiple hierarchical components. However, I don't want these components to be bundled in one single view. How I view it, the current capability of Laravel is to route a single view to one single request. My react component hierarchy is as follows:
Main React App
├─ Subcomponent A
└─ Subcomponent B
However, I only want to fetch each of the subcomponents at certain events in the Main React App. Specifically, I want to get the subcomponents from the server only if the subcomponent will be included in the DOM tree. The fetching must be done with Laravel views.
Is it possible to implement this with Laravel and React?
It is possible, but you will need to manually create Laravel web routes that will allow you to fetch the components. For instance, if Component A requires Component B from server, a web route (or a shared web route) must be made. Here's a demo:
/routes/web.php
// the route which returns your react app engine
Route::get('home-page', function(){
return view('home_page');
});
// the route used to fetch components dynamically
Route::get('react-components/{component_name}', function($component_name){
// you can either wrap your components in blade files
return view('react_components.'.$component_name);
// or manually read them from disk and return them as plain-text responses
return response(
// you can use Storage facade: https://laravel.com/docs/7.x/filesystem
\Storage::disk('react_comps')->get($component_name)
// or primitive method
file_get_contents(base_path().'/views/assets/react_comps/'.$component_name)
);
});
Then, when you want to fetch the component, use the route:
axios.get('/react-components/posts.js')
.then(res=>{
// do stuff with res.data
})

Wildcard route for static content in Angular 7

I am learning Angular 7 by studying this example app. The example app uses a wildcard route to handle all otherwise-unhandled routes.
Specifically, this app-routing.module.ts directs all miscellaneous routes to AppConfig.routes.error404, which is handled by Error404PageComponent.ts, which then ultimately serves up error404-page.component.html for every possible route that is not specified by its own component and named route.
What specific changes would need to be made to the code in this sample app in order for the wildcard route serve different static content for different submitted routes?
For example, if a web user typed in the route /i-am-a-jelly-donut, what changes would need to be made so that the request would 1.) continue to go through Error404PageComponent.ts, but have the user's browser receive a new i-am-a-jelly-donut.page.html instead of the error404-page.component.html view?
The Error404PageComponent.ts would still serve up error404-page.component.html for every non-specified route. However, we would be adding logic to give special handling inside Error404PageComponent for a specific static route in addition to the logic for every non-specified route.
The goal here is to be able to handle static routes without having to create a separate component for each and every route. Think, for example, of a blog where most of the routes have an identical template, but with different content in each blog entry.
Templates are compiled into the components at build time and you are not going to be able to change which template a component uses at runtime but you can hide and show sections based on conditions. Inject the router into your component
constructor(private router: Router) {}
Now you can set a variable on your component based on if the route contains 'i-am-a-jelly-donut'
jellyDonut = this.router.url.indexOf('i-am-a-jelly-donut') !== -1;
and in your template
<ng-container *ngIf="jellyDonut">
Jelly Donut
</ngcontainer>
<ng-container *ngIf="!jellyDonut">
Other stuff
</ngcontainer>

Angular 2 dynamic routing doesn't work when try to access by URL

I am trying to archive dynamic routing in my Angular application. I have completed following functionalities so far.
Add routing to an existing angular component by user input.
Remove routing from an existing angular application.
I have used router.resetConfig to do this.
My problem is that whatever the new dynamic route I have added cannot be accessed by typing in the URL. it gives me following error.
ERROR Error: Uncaught (in promise): Error: Cannot match any routes. URL Segment: 'module3'
Error: Cannot match any routes. URL Segment: 'module3'
Here is my code
app.module.ts
const routes: Routes = [
{
path: '',
component: Module1Component
},
{
path: 'module2',
component: Module2Component
}
];
app.component.html
<div>
<h2><a routerLink="">Module1</a></h2>
<h2><a routerLink="module2">Module2</a></h2>
<h2><a routerLink="module3">Module3</a></h2>
<input type="button" value="add module 3 to route" (click)="addRoute()"/>
<input type="button" value="remove module 3 from route" (click)="removeRoute()"/>
</div>
<router-outlet></router-outlet>
app.component.ts
addRoute(){
let r: Route = {
path: 'module3',
component: Module3Component
};
this.router.resetConfig([r, ...this.router.config]);
console.log(this.router.config);
}
I have found that after trying to access the newly added route by typing it in the browser URL the newly added route object disappears from the route array. Hence I am getting that error.
Following image is before I add the dynamic route object
This is after I add the route object
But when I try to access the /module3 route by accessing it in the URL,
it just reinitializes the route object array and therefore it doesn't contain the newly added route.
My question is how I can persist this newly added route to the initial route object array. So that it will be there when I try to access it by URL.
I have added sample angular project for this scenario in the following GitHub repo.
https://github.com/mal90/ng-dynamic-route
If anyone can point me in the right direction is much appreciated!
Angular is a client side framework so when you add a new route dynamically it's only effective as long as you do not try to access a page from a server request, which is the case when you enter a URL in the browser
As David pointed out, your approach is precise headshot for Angular app. Looking at your profile, you seem to know about Node.js and you have rather good score, so I presume there must be good reason for you going with this highly specific road. If you really want to do such a crazy thing (I cannot see the reason why to do it ... I think you should rather use server-side solution) you might try storing the router definitions in some local storage or external file and force app to redirect any path to some specific route, then to force the app to redefine the router, initialise it again and only then navigate to the new component. As you can see, you will need a lot of force to do this. Some people had already similar ideas. Such as in this post about external definitions Do not take me wrong, I like crazy ideas. You could probably hack the environment somehow. But I think it is not worth it.

Disable vue-router for certain routes? Or how to run SPA backend, and non-SPA frontend?

so I'm developing a website/webapp in Laravel 5.3, and Vue 2. SEO is important, so I'm wanting to keep the frontend/crawable section of the site in Laravel + Blade, and only small non necessary sections in Vue 2.0, so I've not got to use Ajax to load the page content, and allowing crawlers like Google to crawl and index the site. (AFAIK, Google does load JS, but doesn't wait for Ajax to load, so it's hit/miss).
However, on the backend, I want to go fully SPA with Vue and VueRouter.
How do I best separate the two?
I want my backend to be accessible via /manager
My solution so far is to:
# routes.php
### Laravel/Frontend routes go here (before SPA) ###
Route::get('/manager/{spaPlage?}', ['middleware' => 'auth', function () {
return view('manager.index');
}])->where(['spaPlage' => '.*'])->name('manager.index');
and then in Vue, I use:
const routes = [
{ path: '/', name: 'dashboard.index', component: require('./pages/manager/Dashboard.vue') },
{ path: '/categories', name: 'categories.index', component: require('./pages/manager/categories/Index.vue') },
{ path: '/category/:id', name: 'category', component: require('./pages/manager/categories/Category.vue') }
];
const router = new VueRouter({
routes,
base: '/manager'
})
const app = new Vue({
el: '#app',
router
...
Which does work. However, it doesn't feel right. Because the view router still loads on my frontend (appends hash/hashbang).
So, is there a better way to separate my Laravel frontend with my Vue SPA backend?
Just to clarify some misconceptions for anyone in the future.
Google can crawl JS based front end websites without the need to pre-render or server-side render. With one caveat, Google uses Chrome 41 to crawl and render the site, so your javascript has to be polyfilled at least well enough to support Chrome 41 features (or at least your Vue-based data needs to be polyfilled to support Chrome 41). I haven't had any trouble just using babel thus far.
Laravel frontend with my Vue SPA backend
This is backwards. If you are doing this, don't. Laravel should be your backend & frontend (via blade + bootstrap + Vue/react), or your backend only. Vue.js is a frontend framework and shouldn't be used as a "backend." All your database queries, authentication, calculations, emailing, etc. should be handled by Laravel. Laravel is great for backend work and it's completely reasonable to code an entire API up with laravel and use Vue exclusively for front end. Sure you might be able to hack it together and make it somehow work, but you shouldn't, and you'd just be creating extra headache for yourself for no reason.
But to also answer the question, because there is a case to be made for a website that has only part of it's site as an SPA (maybe the blog is an SPA site, but is complete separate from the "about us", "contact us", etc like pages (for instance, you might be revamping a website in parts, and would like to roll out updated pages over time instead of tackling everything at once). In this case you can specify specific routes for Vue Router to run on, and all others will be handled by laravel.
Route::get('/DIR/{vue_capture?}', function () {
return view('vue.index');
})->where('vue_capture', '[\/\w\.-]*');
This would allow Vue Router to handle everything in the DIR sub directory, but allow other routes to coexist along side of it.
But if your application requires Vue Router to have access at the root domain, then just put that at the very end of your routes file, because when route matching is done, it quits after the first match. So by placing it at the end of your routes file, you are essentially using it as a "catch all" for any routes not specified above it. Think of it like returning early.
For anyone who comes across this, I wasn't able to find anything on disabling VueRouter for specific links. I don't think it's possible, also, it's probably not worth the hassle.
So I've decided to re-write all my codebase to be a SPA. It's about time, and there's no real reason not to. I'm using Prerender.io's self hosted service for pre-rendering for SEO, etc.

Categories

Resources