Is it possible to know if route has resolvers or not with router.events?
I tried to find it with:
this.router.events.subscribe(e => {
console.log(e);
})
But it seems that there is no information about resolvers in router events. I need this for progress bar. Maybe ActivatedRoute can be useful in this case? But where exactly should i look? activateRoute.snapshot.data is always empty object
I also tried:
private isRouteHaveResolvers() {
let firstChild = this.activatedRoute.firstChild;
while (firstChild && firstChild.firstChild) {
firstChild = firstChild.firstChild;
}
return firstChild && firstChild.routeConfig && !!Object.keys(firstChild.routeConfig.resolve).length;
}
But it doesnt work properly. For example for this case:
{
path: 'edit',
component: EditComponent,
resolve: {
data: resolverData
},
children: [{
path: 'activity/:activityId',
component: ModalComponent,
outlet: 'modal',
}],
}
For this route activity/:activityId it return true
Related
Navigating to url: site.com/#locallink 'redirects' to site.com, first time entered in the browser - in other words, does not jump to the anchor.
If I simply re-type the url (site.com/#locallink) then it works as expected (jumps to anchor).
I have defined routes and router like so, and history mode as you can see.
let router = new VueRouter({
mode: 'history',
scrollBehavior: function (to, from, savedPosition) {
if (to.hash) {
return { selector: to.hash }
} else {
return { x: 0, y: 0 }
}
},
routes
});
If I have a link on another page to the same anchor, then it works flawlessly. It's only when typed into the browser directly that it does not seem to work - the # part of it get's eaten.
The routes follow this pattern:
export const routes = [
{
path: '/',
name: 'home',
component: require('components/prelogin/landingpage.vue'),
meta: {
title: 'Some title',
metaTags: [
{
name: 'title',
content: '...'
},
{
name: 'description',
content: 'some description here...'
}
]
}
},
...
There are many entries so only showing first.
Any ideas?
Thanks
Hope it will help
scrollBehavior: function (to, from, savedPosition) {
if (to.hash){
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve({
selector: to.hash,
behavior: 'smooth',
})
}, 500)
})
} else {
return { x: 0, y: 0 }
}
}
I have this vuex state
const state = {
clientSide:{
iata:'',
currencyrates:''
},
auth:{
userid:'',
token_string:'',
full_names:'',
email:'',
role:'',
loggedin_status:'',
language:'en',
currency:'USD',
application_name:''
}
};
export default state
that i am updating like this
this.$store.state.auth = response.data;
after successful authentication. I set into the state data like this
{"userid":"6373773738","token_string":"$2y$13$8kBYlKQz5.w3l0JRkMat8uL7nEW5Zxb4LUrxahVAIrNzPZDQDv1zO","full_names":"Josh Does","email":"account#gmail.com","role":"admin","loggedin_status":"loggedin","language":"string","currency":"USD","application_name":"box_overflow"}
I want to to make sure, a user can visit only routes allowed in his/her role and this are some of the routes
{
path: '/view-review',
name: 'view-review',
meta: { title: 'View Review', requiresAuth: true, rolesAllowed: 'guest,admin,marketer', loginPage: '/user_login' },
component: () => import('../views/View_Review.vue')
},
{
path: '/write-review',
name: 'view-review',
meta: { title: 'Write Review', requiresAuth: true, rolesAllowed: 'end_user,admin,marketer', loginPage: '/staff_login' },
component: () => import('../views/Write_Review.vue')
},
In my router
router.beforeEach((to, from, next) => {
document.title = to.meta.title
if (to.matched.some((record) => record.meta.requiresAuth)) {
if (store.state.auth.loggedin_status === 'loggedin' && store.state.auth.role is_in record.meta.rolesAllowed) {
next();
return;
}
window.location.replace(record.meta.loginPage);
} else {
next();
}
});
Does vue router have the ability to check if a role exists in a comma seperated list of allowed roles,for instance like in the pseudocode below
store.state.auth.loggedin === 'loggedin' && store.state.auth.role is_in record.meta.rolesAllowed
You can convert list of roles into an array first and then iterate over looking for given role.
record.meta.rolesAllowed
.split(',') // convert string to array by ',' char
.includes(store.state.auth.role) // check if given role is in array
If record.meta.rolesAllowed is rather long you can convert it to Set before and call has(store.state.auth.role) instead.
Case:
I am trying dynamically mount functional vue component inside custom directive
(I need to show special button, when user hovers on some elements on the page). I do it in this way, dynamically, because I have thousands of elements on the page, so I try to avoid excess components and try to mount them on the fly, while hovering.
Directive code:
import AIcon from './ui/AIcon';
let AIconComponent = Vue.extend(AIcon);
editable: {
bind: (element, binding, vNode) => {
element.addEventListener('mouseover', () => {
element.style.position = 'relative';
let editButtonWrp = htmlToElement(`<div class="btn-wrp"><span class="btn"></span></div>`);
element.prepend(editButtonWrp);
new AIconComponent({
el: editButtonWrp.querySelector('.btn'),
parent: vNode.context,
props: {
size: 'xs', icon: 'edit',
},
});
});
}
}
Button functional component code:
export default {
functional: true,
props: {
icon: {
type: String,
default: '',
},
size: {
type: String,
default: 'md',
}
},
render(createElement, { props }) {
let iconHref = `/dist/img/sprite.svg#${props.icon}`;
return createElement('svg', {
class: { 'a-icon': true, [`-${props.icon}`]: true },
}, [
createElement('use', {
attrs: {
'xlink:href': iconHref,
},
}),
]);
},
}
But on the page I get this error:
TypeError: Cannot read property 'props' of undefined
at Proxy.render (AIcon.js?27d5:19)
As I understand, when I call new AIconComponent({ ... }) in directive, it passes undefind context to render(createElement, { props }) ... but why? How I can resolve this case?
I am using vue-router to redirect to a new URL after clicking on a button. I would like the router to only add a query parameter into the URL if the query parameter is actually filled. So if it is null it should not add the parameter.
Right now this is not working as expected. Have a look at the following code snippet (choose each of the options and click the button).
(it seems you can't use routing on Stackoverflow so please also have a look at the snippet on JSFiddle: https://jsfiddle.net/okfyxtsj/28/)
Vue.use(VueRouter);
new Vue({
el: '#app',
router: new VueRouter({
mode: 'history',
}),
computed: {
currentRoute () {
return this.$route.fullPath
}
},
data () {
return {
some: this.$route.query.some || null
}
},
template: '<div><select v-model="some"><option :value="null">Option (value = null) which leaves empty parameter in URL</option><option value="someParameter">Option (value = someParameter) which shows parameter with value in URL</option><option :value="[]">Option (value = []) which removes parameter from URL</option></select><br><button #click="redirect">Click me</button><br><br><div>Current Path: {{ currentRoute }}</div></div>',
methods: {
redirect () {
this.$router.push({
path: '/search',
query: {
some: this.some || null
}
})
}
},
watch: {
'$route.query': {
handler(query) {
this.some = this.$route.query.hasOwnProperty('some') ? this.$route.query.some : null
},
},
},
watchQuery: ['some']
});
<script src="https://cdn.jsdelivr.net/npm/vue#2.5.17/dist/vue.js"></script>
<script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
<div id="app"></div>
When some is null the parameter will still be added to the URL. When some is an empty array it will not be added to the URL.
I don't want to use an empty array as default value since the value should always be a string.
So how can I make sure the query parameter is only added to the new route if it contains a value other than null?
Use a simple if-else or ternary construct. Also prefer computed property for some instead of watcher:
Vue.use(VueRouter);
new Vue({
el: '#app',
router: new VueRouter({
mode: 'history'
}),
computed: {
some() {
return this.$route.query.some || null;
}
},
data() {
return {};
},
methods: {
redirect() {
const routeConfig = this.some
? { path: '/search', query: { search: this.some } }
: { path: '/search' };
this.$router.push(routeConfig);
}
},
// Remaining config like template, watchers, etc.
});
I need to grab the value of a key form URL. Let's say the URL is http://localhost:8080/foo=bar. How do I grab the value 'bar' onEnter function with in react-router so that it can be used to trigger other functions.
Thank you in advance.
URL: http://localhost:8080/foo=bar
// routes.js
var React = require('react');
var ReactRouter = require('react-router');
var Main = require('./templates/main.jsx');
var Sub = require('./templates/sub.jsx');
module.exports = {
path: '/',
component: Main,
indexRoute: { component: Main },
childRoutes: [
{
path: '/foo=:bar',
component: Sub,
onEnter: function(){
// *****************************
// grab the value 'bar' from param
}
}
]
}
The onEnter function takes two arguments. nextState and transition. The value you're looking for is inside of nextState.params:
onEnter: function(nextState, transition) {
let bar = nextState.params.bar;
}