VueJS: Pass Data Between Routers - javascript

I have tried countless to pass data between views using props and can't seem to get it to work. The idea is to pass data from one route to the other and at the end display all user inputted data.
Component A
<script>
export default {
name: 'DependencyStatus',
data: function () {
return {
efcForm: {
born: false
}
}
},
methods: {
processForm: function () {
this.$router.push({name: 'student', props: {messaged: 1}})
console.log({born: this.efcForm.born,})
}
}
}
</script>
Component B
<script>
export default {
name: 'StudentData',
props: ['messaged'],
data: function () {
return {
born: this.$route.messaged
}
},
methods: {
checkForm: function() {
console.log({checkForm: this.born })
}
}
}
</script>
My routes:
const routes = [
{
path: '/',
name: 'Home',
component: Home,
},
{
path: '/student',
name: 'student',
component: Student,
props: true
},

You can use dynamic param to pass data from one route
component to another.
const routes = [
{
path: '/',
name: 'Home',
component: Home,
},
{
path: '/student/:messaged', // <-- [1] Add dynamic param
name: 'student',
component: Student,
props: true
}
]
Component A:
methods: {
processForm: function () {
this.$router.push({name: 'student', params: { messaged: 1 } }) // <-- [2] pass `messaged` as param instead of prop
}
}
Component B:
methods: {
checkForm: function() {
console.log({ messaged: this.$route.params.messaged }) // <-- [3] excess in the other component via route param
}
}
PS: In case of passing complex ds, consider using Vuex

Related

i want to display to only one user with this condition but getting this error:

Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
You might have mismatching versions of React and the renderer (such as React DOM)
You might be breaking the Rules of Hooks
You might have more than one copy of React in the same app See for tips about how to debug and fix this problem.
navconfig.js
import React, { useState, useEffect } from 'react';
import { useSelector } from 'react-redux';
// component
import Iconify from '../../components/Iconify';
// ----------------------------------------------------------------------
const getIcon = (name) => <Iconify icon={name} width={22} height={22} />;
//get data from signup page
const [state, setState] = useState({
email: '',
password: '',
});
const { email, password } = state;
const { currentUser } = useSelector((state) => state.user);
// console.log('currentuser', JSON.parse(currentUser).email)
useEffect(() => {
const email = currentUser ? JSON.parse(currentUser).email : null;
if (email == "lokesh.kanhasoft#gmail.com") {
const navConfig = [
{
title: 'dashboard',
path: '/dashboard/app',
icon: getIcon('eva:pie-chart-2-fill'),
},
{
title: 'user',
path: '/dashboard/user',
icon: getIcon('eva:people-fill'),
},
{
title: 'product',
path: '/dashboard/products',
icon: getIcon('eva:shopping-bag-fill'),
},
{
title: 'blog',
path: '/dashboard/blog',
icon: getIcon('eva:file-text-fill'),
},
{
title: 'calender',
path: '/dashboard/calender',
icon: getIcon('uis:calender'),
},
{
title: 'login',
path: '/login',
icon: getIcon('eva:lock-fill'),
},
{
title: 'register',
path: '/register',
icon: getIcon('eva:person-add-fill'),
},
{
title: 'Not found',
path: '/404',
icon: getIcon('eva:alert-triangle-fill'),
},
];
}else
{
const navConfig = [
{
title: 'user',
path: '/dashboard/user',
icon: getIcon('eva:people-fill'),
},
{
title: 'product',
path: '/dashboard/products',
icon: getIcon('eva:shopping-bag-fill'),
},
{
title: 'blog',
path: '/dashboard/blog',
icon: getIcon('eva:file-text-fill'),
},
{
title: 'calender',
path: '/dashboard/calender',
icon: getIcon('uis:calender'),
},
{
title: 'login',
path: '/login',
icon: getIcon('eva:lock-fill'),
},
{
title: 'register',
path: '/register',
icon: getIcon('eva:person-add-fill'),
},
{
title: 'Not found',
path: '/404',
icon: getIcon('eva:alert-triangle-fill'),
},
];
}
}, [currentUser]);
export default navConfig;
You should not using hook outside of components I think. You can read more here: https://en.reactjs.org/warnings/invalid-hook-call-warning.html
Dont use hook outside of component, we can know that hook is started with 'use' e.g: useState, useeffect. Hook can only use in a component, component is like
const ThisIsAComponent = () => {return(<div>something you want</div>)}
so if you want use hook you must do like this
const ThisIsAComponent = () => {
const [value, setvalue]=useState()
return(<div>something you want</div>)}
if you use hook like this
const [value, setvalue]=useState()//this hook obviously outside of component
const ThisIsAComponent = () => {
return(<div>something you want</div>)}
it will throw the error that you got

How to hide and deny access to some routes in VueJS with Store state?

After authorization, I write the user type to the state, based on this type, I want to show / hide some routes.
src/store/index.js:
import Vue from "vue";
import Vuex from "vuex";
import getters from "./getters";
import user from "./modules/user";
Vue.use(Vuex);
const store = new Vuex.Store({
modules: { user },
getters
});
export default store;
src/store/getters.js:
const getters = {
token: state => state.user.token,
name: state => state.user.name,
type: state => state.user.type
};
export default getters;
src/router/index.js:
import Vue from "vue";
import Router from "vue-router";
import Layout from "#/layout";
Vue.use(Router);
export const constantRoutes = [
{
path: "/login",
component: () => import("#/views/Login"),
hidden: true
},
{
path: "/",
component: Layout,
redirect: "/dashboard",
children: [
{
path: "dashboard",
name: "Dashboard",
component: () => import("#/views/Dashboard"),
meta: { title: "routes.dashboard", icon: "el-icon-odometer" }
}
]
},
{
path: "/providers",
component: Layout,
redirect: "/providers/list",
name: "Providers",
meta: { title: "routes.providers", icon: "el-icon-suitcase-1" },
children: [
{
path: 'list',
name: "List",
component: () => import("#/views/providers/ProvidersList"),
meta: { title: "routes.providersList", icon: "el-icon-document" }
}
]
}
];
const createRouter = () =>
new Router({
scrollBehavior: () => ({ y: 0 }),
routes: constantRoutes
});
const router = createRouter();
export function resetRouter() {
const newRouter = createRouter();
router.matcher = newRouter.matcher;
}
export default router;
Authorization control in a separate file src/permission.js:
import router from "./router";
import store from "./store";
import { Message } from "element-ui";
import NProgress from "nprogress";
import "nprogress/nprogress.css";
import { getToken } from "#/utils/auth";
import getPageTitle from "#/utils/get-page-title";
NProgress.configure({ showSpinner: false });
const whiteList = ["/login"];
router.beforeEach(async (to, from, next) => {
NProgress.start();
document.title = getPageTitle(to.meta.title);
const hasToken = getToken();
if (hasToken) {
if (to.path === "/login") {
next({ path: "/" });
NProgress.done();
} else {
const hasGetUserInfo = store.getters.name;
if (hasGetUserInfo) {
next();
} else {
try {
await store.dispatch("user/getInfo");
next();
} catch (error) {
await store.dispatch("user/resetToken");
Message.error(error || "Has Error");
next(`/login?redirect=${to.path}`);
NProgress.done();
}
}
}
} else {
if (whiteList.indexOf(to.path) !== -1) {
next();
} else {
next(`/login?redirect=${to.path}`);
NProgress.done();
}
}
});
router.afterEach(() => {
NProgress.done();
});
As you can see all the code is a collection of copy-paste solutions found somewhere and now I'm completely stuck. How can I hide and deny access to certain routes for users with different state.user.type?
Converting my comment to answer.
Perhaps it will be easier (for you) to use an existing (and tested) solution - something like Vue-ACL or even more advanced.

How Test MapGetter

I would like to test if my getter is called in my component or view, but I don't understand how can it.
My method in the component :
computed: {
...mapGetters({ item: 'moduleA/getData' }),
},
And this is my unit test declaration :
beforeEach(() => {
store = new Vuex.Store({
modules: {
moduleA: {
state: {},
getters: {
getData() {
return { item: { name: 'test' } };
},
},
},
},
});
wrapper = shallowMount(MyComponent, {
store,
});
});
And I try to test if the data is loaded in my template:
it('should check if name is thruthy', () => {
expect(wrapper.find('.classA').text()).toEqual('test');
});
my component :
<template>
<v-content>
<ComponentA v-if="item.name"
key="keyA" ></ComponentA>
<ComponentB v-else key="keyA"></ComponentB>
</v-content>
</template>
<script>
import { mapGetters } from 'vuex';
import ComponentA from '#/components/ComponentA.vue';
import ComponentB from '#/components/ComponentB.vue';
export default {
/**
* Component's name :
*/
name: 'ViewA',
/**
* Component's used :
*/
components: {
ComponentA,
ComponentB,
},
/**
* computed's used :
*/
computed: {
...mapGetters({ item: 'moduleA/getData' }),
},
};
</script>
and my getter in the moduleA :
const getters = {
getData: state => state.data,
};
But I have this message:
TypeError: Cannot read property 'name' of undefined
Why? Thank you for your help.
As shown in docs, shallowMount's options has field named localVue. To solve your problem you should create a localVue, using createLocalVue and pass it to shallowMount.
createLocalVue returns a Vue class for you to add components, mixins
and install plugins without polluting the global Vue class.
import Vuex from 'vuex'
import { createLocalVue, shallowMount } from '#vue/test-utils'
beforeEach(() => {
const localVue = createLocalVue()
localVue.use(Vuex)
store = new Vuex.Store({
modules: {
moduleA: {
state: {},
getters: {
getData() {
return { item: { name: 'test' } }
},
},
},
},
})
wrapper = shallowMount(MyComponent, {
localVue,
store,
})
})

Vuejs pass value from instance to component

I want to pass a value from my vue instance to my vue component.
I have following vue component (vuejs dropzonejs component), which das basically a nice Image upload ui.
<template>
<vue-dropzone ref="myVueDropzone" id="dropzone" :options="dropzoneOptions"></vue-dropzone>
</template>
<script>
import vue2Dropzone from 'vue2-dropzone'
import 'vue2-dropzone/dist/vue2Dropzone.css'
export default {
name: 'app',
components: {
vueDropzone: vue2Dropzone
},
data: function() {
return {
game: {
title: ''
},
dropzoneOptions: {
url: '/games/upload',
method: 'post',
params: {
title: this.game.title
}
}
}
},
methods: {
processFiles () {
this.$refs.myVueDropzone.processQueue();
},
getGameTitle () {
this.game.title = '',
}
}
}
</script>
I Need to get the game title from my vue instance and pass it to my vue component so that I can do some work there with that title.
My vue instance Looks like this:
require('./bootstrap');
window.Vue = require('vue');
Vue.component('vue-dropzone', require('./components/ImageDropzoneComponent.vue'));
const app = new Vue({
el: '#app',
data: {
loading: false,
title: '',
},
methods: {
createGame (e) {
this.uploadImage();
axios.post('/games', {
title: this.title,
})
.then((response) => {
console.log(response.data);
})
.catch((error) => {
console.log(error);
})
},
uploadImage () {
this.$refs.myVueDropzone.processFiles()
},
getGameTitle () {
return this.title;
}
}
});
The tag:
<vue-dropzone ref="myVueDropzone"></vue-dropzone>

Import vue.js component

I need import component with data into vue.js app.
I can component registration and I used this code.
Correct Code:
export default {
name: 'hello',
data () {
return {
msg: 'Welcome to Your Vue.js App'
}
},
components: {
'test': {
template: '<div>msg: {{message}}</div>',
props: {
message: {
type: String,
required: true
}
}
}
}
}
But how can I Local Registration with data?
NOT correct:
import Test from './components/Test.vue';
export default {
name: 'hello',
data () {
return {
msg: 'Welcome to Your Vue.js App'
}
},
components: {
'test': {
template: Test,
props: {
message: {
type: String,
required: true
}
}
}
}
}
This should work
import Test from './components/Test.vue';
export default {
name: 'hello',
data () {
return {
msg: 'Welcome to Your Vue.js App'
}
},
components: {
Test
}
}
And if you want to pass props
<template>
<Test :message=msg></Test>
</template>
I use props in component code (components/xxx.vue) and resolved it.

Categories

Resources