I have a pretty simple page right now that I'm just setting up for future development but it's kind of come to a halt now that my URL keeps getting changed.
import shipmentInformation from './shipment-information.vue';
Vue.use(VueRouter);
let router = new VueRouter({
base: '/QuickQuote/QuickQuoteRefactor/',
routes: [
{ name: 'shipmentInformation', path: '/', component: shipmentInformation }
]
});
new Vue({
router
}).$mount('#quickQuoteApp')
This is run on a page where #quickQuoteApp contains a <router-view> element. Users get to this page by navigating to (on local machine) localhost/QuickQuote/QuickQuoteRefactor. The components load and I see the hash get added to the end of the url for a split second (localhost/QuickQuote/QuickQuoteRefactor#) before it changes to localhost/#/ for some reason.
Any ideas on why this is happening. I thought the 'base' option was supposed to take care of this.
I discovered that this was caused by a conflict between vue-router and jquery.history.js
Not sure of the exact cause but it looked like History was trying to 'correct' the hash changes in the url made by vue-router, therefore breaking it.
Related
I am creating angular application that will handle documentation for my GitHub apps, in more complex way than just readme files. I want to redirect user after clicking in topnav dropdown to selected route, but there's problem with router. (I need to redirect with some parameters, but it doesn't work even with simple path reditect). Those methods redirect to target route for like 1 seconds (like excepted), then user got redirected back to root page.
Code:
/* First element is project name, second is category/part of application name */
choices = ["typing_speed_test", "overview"]
json = json
constructor(private router: Router){}
onProjectClick($event){
this.choices[0] = $event.target.innerHTML.trim();
this.choices[1] = "overview";
this.redirect();
}
onCategoryClick($event){
this.choices[1] = $event.target.innerHTML.trim();
this.redirect();
}
redirect(){
this.router.navigateByUrl("404");
}
Routes:
const routes: Routes = [
{ path: '', component: HomeComponent },
{ path: 'project/:project_name/:category', component: SubpageComponent },
{ path: '404', component: NotFoundComponent },
//{ path: '**', redirectTo: '404', pathMatch: 'full' }
];
Link to gif with problem: https://imgur.com/a/x2mPxvh
Full code in github repo: https://github.com/Dolidodzik/DocsForMyApps (if you used code from here to answer this question, please point that in your answer)
I think I may did some stupid mistake, because I am pretty new in Angular, but I couldn't do it, because every google question showed me solves for ERRORS, when redirect doesn't work at all, not to bugs like in my situation.
You need to remove the href="#" from your anchor links in your navigation bar. It's causing the browser to reload:
<a class="dropdown-item" *ngFor="let item of categories() | keyvalue">
{{item.key}}
</a>
Also this is a bit weird solution:
this.choices[0] = $event.target.innerHTML.trim();
You better just send the item variable in your function call in your template, and you can then read this in your component event handler:
onProjectClick(item){
this.choices[0] = item.key;
this.choices[1] = "overview";
this.redirect();
}
the problem is your lins look like this:
link
default link behavior causes your app reload from the start. you should use [routerLink]="['someUrl']" instead of href. If you need that href in some cases, consider calling $event.preventDefault() to cancel the native browser navigation
Parasails.js documentation mentions that it does support router and virtualPages, but does not actually specify how to interact with these options.
I am somewhat used to the normal Vue setup, of importing Vue, VueRouter and each individual component directly into the .vue file.
But with parasails.js, I feel that these parameters are expecting objects that are not defined in the documentation, so I'm just guessing at this point.
I have gotten to this point so far:
parasails.registerComponent('mainSearch', {
props: [
'prop1',
'prop2',
],
html5HistoryMode: 'history',
virtualPages: [
{ path: '/foo', component: 'page2' },
],
template: `
<div class="test">
<p>Test</p>
<router-link to="/foo">Foo</router-link>
<router-view />
</div>
`,
beforeMount: function() {
//…
// Attach any initial data from the server.
_.extend(this, SAILS_LOCALS);
},
mounted: async function(){
//…
},
beforeDestroy: function() {
//…
},
});
But I am receiving the error:
TypeError: In the HTML template (during render): Cannot read property 'matched' of undefined
Has anyone successfully used router or virtualPages in parasails.js and can help me out?
Also, my next question is: When passing components to virtualPages, do I just supply the name of another parasails registered component as a string? Or do I have to include that component in the code, and pass it as an object as one would do in VueRouter?
Thanks for any and all help!
EDIT
Using virtualPages on a parasails component apparently will not work.
But adding these properties to a parasails page seems to be the intended usage:
virtualPages: true,
html5HistoryMode: 'history',
virtualPageSlug: undefined,
virtualPagesRegExp: /^\/test\/?([^\/]+)?/,
Now, although I am no longer receiving errors, the <router-view></router-view> element is not being populated with the proper view when the <router-link to="/test/foo/">Foo</router-link> is clicked on the page.
I have added the following route to the project
'/test/foo/' : {
view: 'pages/test'
},
Any clues as to why my router-view is not being updated properly?
I think this documentation requires some serious updates as this is a pure guessing game every step of the way.
You're right, that link you provided does seem like its missing some info on how to set the virtual pages. I dont know much about using just parasails but in Sails v1 this is how I set virtual pages. (I use this mostly to have linkable modals.)
In your page script you define your data:
virtualPages: true,
html5HistoryMode: 'history',
virtualPageSlug: undefined,
virtualPagesRegExp: /^\/foo\/bar\/?([^\/]+)?/,
In your ejs file you can add this to a wrapping div:
v-if="virtualPageSlug === 'new'"
Routes file:
'GET /foo/bar/:virtualPageSlug?': { action: 'foo/view-bar' },
I am setting my router follow this guide
https://router.vuejs.org/en/advanced/lazy-loading.html
const PageWaitingRoom= () => import(/* webpackChunkName: "group-CCManageBusiness" */'./../pages/customer-care/manage-business/PageWaitingRoom');
const Routes = [
{
path: '/customer-care/manage-business/waiting-room',
component: PageWaitingRoom,
name: PageWaitingRoom.name
}
]
And in another page, I use router-link like this:
<router-link class="nav-link text-uppercase"
:to="{name: 'PageWaitingRoom'}"
exact>
Waiting Room
</router-link>
Everything work fine until I use webpack to make production build with UglifyJsPlugin, the router-link not resolve the url, it always point to root url instead. I must change the router-link to not use the name like this:
<router-link class="nav-link text-uppercase"
to="/customer-care/manage-business/waiting-room"
exact>
Waiting Room
</router-link>
But I don't want to do by that way, I refer to use component name in the router-link, since it is shortly and easy to me to change the url in the future.
This problem is only happen when I use UglifyJsPlugin, I am not sure what I am missing.
Anyone are facing this problem like me? Please give me advice.
Thanks!
If you want you preferred version to work you need to disable mangling, like so:
new webpack.optimize.UglifyJsPlugin({
mangle: false
})
This should stop it messing with your route name but note that this also stops the obfuscation of the code. You can do a Google search to decide whether this is a problem or not. Some people say yes, others no.
I have disabled this option in my latest app with the reasoning that if someone is determined enough, renaming PageWaitingRoom to xyz isn't going to stop them, only slow them down.
Actually I did not named the route by a string, but I used the name of the component as the route name instead, like below, and it makes my stupid poblem lol:
const Routes = [
{
path: '/customer-care/manage-business/waiting-room',
component: PageWaitingRoom,
name: PageWaitingRoom.name //<-- UglifyJsPlugin will do its business and cause the route issue.
//name: 'PageWaitingRoom' <-- Should use this
}
]
I'm working in a 404 error page functionality, I got it to work with:
const router = new VueRouter({
routes: [
// ...
{
path: '*',
component: NotFound,
name: '404',
meta: {page_title: 'Vuejs&Material Demo | 404 NOT FOUND'}
},
]
});
// ... not found something
this.$router.push({name: '404'});
The problem with the above is that the url changes too, but I just want the view (component) to change.
I find very annoying when a simple typo redirects to a http://example.com/404, it makes me type the url again or go from the browser autofill, either way I don't like it.
I was wondering if there is some sort of method/logic to have something like this: https://www.facebook.com/sdfsd/sfsdf/asfasfsafastgtgregre .
Bottom line, I want for the view to change but not the url.
Is there any vue/vue-router way to do this?
This is a little hacky, but you could update the route via the router's history object's updateRoute method:
let route = this.$router.match({ name: '404' });
this.$router.history.updateRoute(route);
I'm trying to use plainroutes in order to create a react-router profile. I'm not convinced plainroutes is the most readable way to write code, but I'm trying to give it a fair shot since everyone seems excited about it. I'm having an extremely frustrating time trying to define multiple layouts for my components. Take the following working code:
Working plainroutes example
export const createRoutes = (store) => ({
path : '/',
component : CoreLayout,
childRoutes : [
LoginView(store),
SignupView(store),
Activate(store),
ForgotPw(store),
ConfirmReset(store)
]
}
)
Nothing unexpected happening here. The actual routes are built into the views using the following structure (LoginView for example):
Directory structure of childRoute objects
-/Login
--index.js
--/components
--Loginview.jsx
--Loginview.scss
The index.js files contain little route blocks looking like this:
Example childroute
export default (store) => ({
path : 'activate',
component: ActivateView
})
I'll also include the source of the Login component below, as referred to above. Please note I did try adding path: 'login' to this component but it made no difference.
Login import
export default {
component: LoginView
}
When a user visits /login they see the login component. Easy right? Yep. Now you might notice all those routes look like a group of authentication-related views. I want those views to share a layout. In this case, CoreLayout. That's also working with the above code.
Next step is that I want to add a user dashboard for after users login. This dashboard needs to use a different layout which I'm calling LoggedIn. Naturally, I expected that adding another json object with a similar pattern could accomplish this, so I produced the below code:
Broken multiple layout attempt
export const createRoutes = (store) => ({
path : '/login',
component : CoreLayout,
indexRoute : Login,
childRoutes : [
SignupView(store),
Activate(store),
ForgotPw(store),
ConfirmReset(store)
]
},
{
path : '/',
component : LoggedIn,
indexRoute : Home,
childRoutes : [
]
}
)
The above code does not work as intended. The only path that works are that paths in the second element of the set (the one with the / route). I tried moving some routes from the first element down and the do work when put in the second element... but this obviously doesn't solve my problem.
The most frustrating thing to me is that it seems to me as if I am following the SO posts which deal with this, though its a little difficult to tell for sure because they don't use plainroutes. I'm linking one here for reference.
Typing this out actually helped me work through the problem. Nothing like a good rubber duck. It looks like I misunderstood the nature of the router object. Apparently it needs to be a legitimate object, where I was under the impression it was accepting a collection. Thus, you need to define everything within the scope of a single parent. See below for how I solved it for my particular example:
export const createRoutes = (store) => (
{
path : '/',
component : CoreLayout,
indexRoute : Home,
childRoutes : [
{
path : '/',
component : AuthLayout,
childRoutes : [
LoginView(store),
SignupView(store),
Activate(store),
ForgotPw(store),
ConfirmReset(store)
]
},
{
path : '/admin',
component : LoggedIn,
indexRoute : Home,
childRoutes : [
]
}
]
}
)