How to use html templates with Vue CDN and Vue-router CDN? - javascript

I have a problem. I'm doing a software project for university but they want us to use python. Front end in javascript is allowed though and since this is a special course for non CompSci people or programmers even I decided to use the CDN version of vue and vue-router to avoid npm, node, etc to make it easier for them.
So now I have my routes defined like this in index.html inside a script tag defined below everything,
<script src="views/dashboard/dashboard.js"></script>
<script src="views/input/input.js"></script>
<script src="views/info/info.js"></script>
<script src="views/settings/settings.js"></script>
const routes = [
{ path: '/', component: Dashboard },
{ path: '/input', component: Inputpage },
{ path: '/info', component: Infopage },
{ path: '/settings', component: Settingspage },
{ path: '/index.html', redirect: '/' } //default route. Leave this as such to
];
and Dashboard/Inputpage/.. etc are .js files I import. Info.js looks like this for example
var Infopage = {
template: '<h1>This page is for information</h1>'
};
And that displays just fine. However, when I add anything else like a p or something simpler like a second heading, a paragraph or an input, nothing happens. What can I do to have it display more than just a heading?
EDIT 1: I tried
var Infopage = {
template:`<div id='info_page'>
<h1>This page is for information</h1>
</div>`
};
And now I get the error [Vue warn]: Error in nextTick: "InvalidCharacterError: String contains an invalid character".

Related

opening page in new tab getting 404 error

I am trying to open page in new tab, in local it was working fine when deployed to server getting error as below:
Oops, looks like the page is lost.
This is not a fault, just an accident that was not intentional.
Below is my code:
Router:
const routes: Routes = [
{ path: ' ', redirectTo: 'home', pathMatch: 'full' },
{ path: 'home', component: HomeComponent },
{ path: 'resource', component: ResourceDetailsComponent },
{ path: 'careers', component: CareerComponent }
];
#NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
In component:
<a class="view" (click)="redirect(a)"
>VIEW MORE VACANCIES</a
>
redirect(){
localStorage.removeItem("selectedCareer");
window.open("/careers", '_blank');
}
In local page is redirecting and working fine, anything i have missed in my code please let me know.
You are probably trying to access some suburl like yourhomepage.com/resource right?
Your local Development Server will always serve the index.html per default and you probably want to configure your deployment server the same way. You need the index.html file to be served for your angular spa to work. Without knowing your Provider/Server there is no real way to help you with that.
Most Webservers are configured to always return the file you are accessing through the url or the index.html if you provide no suburl.
So if your file tree looks like this:
index.html
angular.js
yourhomepage.com and yourhomepage.com/index.html will return the index.html
and yourhomepage.com/angular.js will return the js file.
BUT yourhomepage.com/ressouces will not return anything because there is no corresponding file. But you can configure your Webserver to also return the index.html in that case.
This is what you probably have to do.

In Angular, how can one component to have multiple HTML templates?

I am developing an ecommerce application, and one major feature is that this app should have multiple themes. The total number of themes could be 100 or even more. However, these themes all have the same data (For example: all home page have same banner images, new product, feature product data.) .
I know I can use ng-template or TemplateRef to determine which piece of HTML should display. But since I have over 100 themes, both ng-template or TemplateRef methods will load a lot of extra files. So I think I need some sort of lazy load, when a component loads the data then lazy loads the correct HTML template. So how can I have this work?
Looks like it is possible, all our routes are handled by lazy loaded modules. This is our out-of-the-box route config:
const routes: Routes = [
{ path: '', loadChildren: () => import('./lazy/lazy.module').then(m => m.LazyModule) }
];
While module lazy has this route config:
const routes: Routes = [
{ path: 'home', component: HomeComponent },
]
While HomeComponent is taken from the declarations of module lazy.
Then define another module, called for example lazy-two with the same route config, and its own HomeComponent.
Finally, you can switch between the modules by using this code:
lazyLoad() {
const routes: Routes = [
{
path: '',
loadChildren: () => import('./lazy-two/lazy-two.module')
.then(m => m.LazyTwoModule)
}
];
this.router.resetConfig(routes);
this.router.navigateByUrl('/home');
}
This will lazy load module lazy-two and refresh the route to /home - you will see the component of the new module displayed.
I couldn't create a stackblitz, some errors occurred probably because of lazy loading. So I ran it locally on my machine and pushed the code to GitHub
EDIT I managed to make a StackBlitz
I recommend used ComponentFactoryResolver to create the components that you need to render.
this.templates = [
{
id: "template-1",
component: Template1,
},
{
id: "template-2",
component: Template2,
},
];
ngOnInit() {
this.templates.forEach((element) => {
this.containerReference.createComponent(
this.factoryResolver.resolveComponentFactory(element.component)
);
});
}
in the .html you should have
<ng-container #containerReference><ng-container>
what about using the same component and styling it different when you select the template?

Why can't I use require in vue-router routes.js?

When using vue-router the standard set up is
main.js requires the routes.js file, which will look something like this
//routes.js
import Register from './components/Register'
import Login from './components/Login'
module.exports = [{
path: `/`,
component: Login,
}, {
path: `/register`,
component: Register,
}]
My question is why can I just do
//routes.js
module.exports = [{
path: `/`,
component: require('./components/Login'),
}, {
path: `/register`,
component: require('./components/Register'),
}]
When I try it, I get this console error
Vue warn]: Failed to mount component: template or render function not defined.
found in
---> <Anonymous>
<App> at src/App.vue
<Root>
**import and require work differently see the link bellow there are good documentation about the topic. **
es6 features
and require how Actually Works
**see the document how node js work under the hood how module.export work what is the nodejs design pattern (how node js wrap our code within Immediately invoked function expression and pass code into v8 engine)
you can simply midify your routes.js file
component:() => import('./components/Register.vue') or
component: require('./components/Login.vue').default
both will work
[{ path: '/', component:() => import('./components/Register.vue') },
{ path: '/register', component: require('./components/Login.vue').default }];

Angular 6: How to use multiple loadChildren with same route?

I have something like:
const routes: Routes = [
{
path: ':path', component: SiteRoot, children: [
{ path: '', loadChildren: '../modules/maple/template.module#TemplateModule' }
]
}
];
I wish to use this :path url to match multiple module dynamically. each module have there own internal Route.
Is there any way I can achieve this?
I tried ViewContainerRef with ResolveComponentFactory but it does not work with module only component. Event with NgModuleFactoryLoader, Routes cannot be applied.
EDIT, to make everything clear:
What I am trying to achieve is to have different module display on same route path. For example user can see user dashboard at "home" path, and admin can see admin dashboard at "home" path as well.
This feature is defined by business logic, so, I cannot change admin dashboard to another url
I think you are trying to create your routing module incorrectly. Anyway, you should write why you need this. I'll try to answer. Every module should have it's own path, so routing module should be strict and static. If you trying it for security, use guards and hide item from menu component.
If you need URLs like this: "/username1/profile", "/username2/profile" you can simply use code like yours, or use lazy loading. create routing file for parent module:
{ path: ':username', loadChildren: '../users/user.module#UserModule' }
Than create routing file for child module:
{ path: '', loadChildren: 'UserComponent', children: [
{ path: '', redirectTo: 'profile' },
{ path: 'profile', component: ProfileComponent}
]
}
Updated By your case:
by your case you can change your HTML file. For example in app.component.html if your code is:
<div>
<router-outlet></router-outlet>
</div>
You can change it with:
<div *ngIf="isLoggedIn | async">
<admin-panel></admin-panel>
</div>
<div *ngIf="(!isLoggedIn | async)">
<router-outlet></router-outlet>
</div>

How to define new router?

For this question I am referring to the vuestic-admin template from https://github.com/epicmaxco/vuestic-admin
This template is the most suitable template for me. However, I want to make some changes. To be exactly, I want to add a new page, but dont want this page shown in the sidebar. To do this I need to define new router. My problem is: I dont quite understand how to add new router.
Hier is what I have done:
Firstly, I made a .vue file in components/contact/Contact.vue. Its code:
<template>
<div class="contact">
<div class="row">
<div class="col-md-12">
<p>contact</p>
</div>
</div>
</div>
</template>
<script>
export default { name: 'contact' }
</script>
<style lang="scss"></style>
Secondly, I added a new .js file in store/modules/contact.js. Its code:
import lazyLoading from './lazyLoading'
export default {
name: 'Contact',
path: '/contact',
component: lazyLoading('contact/Contact'),
meta: {
default: false,
title: 'menu.contact',
iconClass: 'vuestic-icon vuestic-icon-extras'
}
}
Thirdly, in the store/modules/menu/index.js file, I changed the state defination by adding pages:
import contact from './contact'
const state = {
pages: [
contact
],
items: [
dashboard,
statistics,
forms,
tables,
ui,
extra,
auth
]
}
Fourthly, in router/index.js file, I made following changes:
export default new Router({
routes: [
...generateRoutesFromMenu(menuModule.state.items),
{path: '*', redirect: { name: getDefaultRoute(menuModule.state.items).name }},
...generateRoutesFromMenu(menuModule.state.pages),
{path: '*', redirect: { name: getDefaultRoute(menuModule.state.pages).name }}
]
})
By compiling the changes above I get the console error: Uncaught TypeError: Cannot read property 'name' of undefined
Based on my knowledge (and my guess) the problem should be in the fourth step.
Could anybody please show me a way out of this problem? Thanks a lot!
Looking at the source here for getDefaultRoute(),
function getDefaultRoute (menu = []) {
let defaultRoute
menu.forEach((item) => {
if (item.meta.default) {
defaultRoute = item
} else if (item.children) {
let defaultChild = item.children.find((i) => i.meta.default)
defaultRoute = defaultChild || defaultRoute
}
})
return defaultRoute
}
I would say that you don't need the line
{path: '*', redirect: { name: getDefaultRoute(menuModule.state.pages).name }}
since for contact you have set default: false and there are no children, which means the function returns null (hence the error message you received).
The framework seems to assume a single list of menu items and one of them to be set as default. But I think your approach should work.
The only potential problem is that it looks like you are changing framework code, which means a bit more work when upgrading to next version of the framework.
A note about upgrading
I just ran the basic install, and looking at the project I have to revise my remark about a potential upgrade problem.
Essentially, this is a template not a framework. The difference is that the installer creates starter code in your project's src folder, which you can freely modify and save to a github repository.
There is no package under node_modules that would overwrite your router changes when you run npm install on your project at a future date.
If epicmaxco create a new version of the template that you wish to use, you would simply create a new project and copy the changes you previously made within src to the new project (perhaps run a diff of the old and new src folders).

Categories

Resources