How to pass app data to a VueRouter component - javascript

I am using VueRouter to load templates depending on the URL. When I try to use a property defined in app.data in the components, I receive a [VueWarn] Property or method "role" is not defined.
How can I pass every data property to the child components?
This is my script:
const Home = { template: '<p>home page, {{role}}</p>' }
const NotFound = { template: '<p>Page not found</p>' }
const routes = [
{path: '/', component: Home}
{path: '*', component: NotFound}
]
Vue.use(VueRouter)
var app = new Vue({
el: '#app',
data: {
role: 0,
cookiesAlert: true
},
router: new VueRouter({routes})
})

I think your router construction options are not set properly. Usually, I prefer to use 'named routes', therefore what I will set is:
const router = new VueRouter({
routes: [
{ name: 'role', path: '/:role', component: User },
{ path: '*', component: Home }
]
})
And if I don't understand your question wrong, what you want to do is pass the 'data' in parent components to child components via url and read the data in child component?
const User = {
template: '<div><br/>Role read from url is {{ $route.params.role }}</div>'
}
const Home = {
template: '<div><br/>Welcome</div>'
}
const router = new VueRouter({
routes: [
{ name: 'role', path: '/:role', component: User },
{ path: '*', component: Home }
]
})
new Vue({
router,
el: '#app',
data: {
role: 'default role'
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue-router/3.0.2/vue-router.min.js"></script>
<div id="app">
The role is (Please change the 'role' value and click on '/User' link): <input v-model="role" type="text" /> <br/>
<router-link :to="{ name: 'role', params: { role: role }}">User</router-link>
<router-link to="/">Home</router-link>
<router-view></router-view>
</div>
Or if you don't want to use $route.params.role, what I will do is to set the 'props' in router config options to be true.
When props is set to true, the route.params will be set as the component props.
const router = new VueRouter({
routes: [
{ name: 'role', path: '/:role', component: User, props: true },
{ path: '*', component: Home }
]
})
And bind to the 'props' inside child components.
const User = {
props: ['role'],
template: '<div><br/>Role read from url is {{ role }}</div>'
}

Related

VueJS | How can i get url parameters in vue.js?

Hi I'm making my own websites. and i'm newbie vue.js
I'm trying to get parameters to url.
I've been trying to any method. but not works.
Here is a url. -> example.com:8080/login
in this page, there's a button to register.
All i want is when i give url parameter(example.com:8080/login?id=hello&pw=1234), in login.vue, insert value -> user_id = hello, user_pw = 1234 and going back to exapmle.com:/8080
i'm trying to using vue.router. but it not works.
the error is
javax.servlet.ServletException: Circular view path [error]: would dispatch back to the current handler URL [/error] again. Check your ViewResolver setup!
and this is /router/index.js
import Vue from 'vue'
import VueRouter from 'vue-router'
import Main from '../views/Main.vue'
import Login from '../views/Login.vue'
import Intro from '../views/Intro.vue'
import Info from '../views/Info.vue'
import Setting from '../views/Setting.vue'
import store from '../store'
import user_id from '../views/Login.vue'
import user_pw from '../views/Login.vue'
Vue.use(VueRouter)
const routes = [{
path: '/',
redirect: '/main',
},
{
path: '/login',
name: 'login',
component: Login,
},
{
path: '/signup',
name: '/signup',
component: SignUp
},
{
path: '/main',
component: Main,
beforeEnter(to, from, next) {
if (store.state.accessToken) {
next();
} else {
next('/login');
}
},
children: [{
path: '',
name: 'intro',
component: Intro,
},
{
path: '/info',
name: 'info',
component: Info,
},
{
path: '/setting',
name: 'setting',
component: Setting,
},
]
},
]
const router = new VueRouter({
mode: 'history',
base: process.env.BASE_URL,
routes: Login
});
var myApp = new Vue({
router,
el: '#app',
mounted: function() {
let parameters;
parameters = this.$route.query
console.log(parameters)
user_id = this.$route.query.id
user_pw = this.$route.query.pw
}
})
export default router
and this is part of login.vue
export default {
name: "test",
function() {
return {
id: "",
pw: "",
};
},
methods: {
test() {
axios.post("/login", {
id: this.userId,
pw: this.password
})
.then(function(response) {
if(response.data.code === 200) {
}
})
},
mounted : function() {
this.load();
}
}
i don't know what is wrong in my code.
my explain is too bad. sorry. but i'm trying to do my best
You are assigning routes to the Login component.
Replace
const router = new VueRouter({
mode: 'history',
base: process.env.BASE_URL,
routes: Login
});
with
const router = new VueRouter({
mode: 'history',
base: process.env.BASE_URL,
routes
});
"Hello world" example (Maybe it will be helpful). Click on the link to get utm_source:
const User = {
template: `<div><b>User:</b> {{ this.$route.params.id }} | <b>utm_source:</b>
{{this.$router.currentRoute.query['utm_source']}}</div>`
}
const router = new VueRouter({
routes: [
{ path: '/user/:id', component: User }
]
})
const app = new Vue({ router }).$mount('#app')
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
<div id="app">
<nav>
<router-link to="/user/foo?utm_source=facebook">Click her to see the utm_source=facebook of /user/foo?utm_source=facebook</router-link>
</nav>
<router-view></router-view>
</div>

Vue / vue-router scoping

import ExpenseView from './path'
import template from './path'
const MainComponent = new Vue({
el: '#app',
data: {
expense: [{ description: 'expense description', amount: 14.99, _id: 'l;dkfjg;ladfjg;klafjg;l' }],
},
router: new VueRouter({
routes: [
{ path: '/dash', component: ExpenseView, props: { default: true, expenses: MainComponent.expense } },
]
}),
template,
created() {...},
methods: {...},
computed: {...}
})
My goal is to have the router listen to the data in MainComponent but there are scoping issues - MainComponent is not defined.
Is there a way to get the router listening to the data in MainComponent with the way this is structured?
You can see the following example
//you can try the following code
//index.js
import Vue from 'vue'
import Router from 'vue-router'
Vue.use(Router)
import RSSFeed from '#/components/RSSFeed.vue'
export default new Router({
routes: [
{
path: '/rss-feed',
name: 'RSSFeed',
component: RSSFeed,
props: { authorName: 'Robert' }
},
]
})
//RSSFeed.vue
<template>
<ol id="feed">
{{authorName}}
</ol>
</template>
<script>
import Post from './Post'
export default {
props: ['authorName'],
data () {
return {
items: [
{
"title":"Vuejs Nodejs",
"pubDate":"20-07-2018",
"description":"Leading vuejs nodejs",
"link":"https://hoanguyenit.com"
}
],
errors: []
}
}
}
</script>
Example
//in router
const router = new VueRouter({
routes: [
{ path: 'YOUR__PATH', component: Home, props: { authorName: 'Robert' } }
]
})
//in Home.vue
//And inside the <Home /> component,
var Home = Vue.extend({
props: ['authorName'],
template: '<p>Hey, {{ authorName }}</p>'
});

Trouble getting data from root Vue instance with vue-router

I load all of my data in the root Vue instance and im trying to access them in my router.
How can I access the data in my root instance within my router? All the this.a.app or this.app answers i found online weren’t the solution.
Router.js:
import Vue from 'vue'
import Router from 'vue-router'
import Login from '../components/login'
import Container from '../components/container'
Vue.use(Router)
export default new Router({
mode: 'history',
routes: [{
path: '/login',
name: 'Login',
component: Login,
props: { test: **<data from my Vue root instance>** }
},
{
path: '/products',
name: 'Container',
component: Container,
children: [{
path: 'flavor',
component: Login
},
{
path: 'storage',
component: Login
},
{
path: 'network',
component: Login
}
]
}
]
})
Main.js:
import router from './router’
var vm = new Vue({
el: ‘#app’,
router,
template: ‘’,
components: {
App
},
data() {
return {
modal: ‘’
I would avoid sharing the data using the router instance.
I personally like to have a store file, which contains data I want to share between my components.
export default {
state: {
counter: 0
}
}
And in your component you can import the file:
import store from '../store'
export default {
data () {
return {
sharedState: store.state
}
}
}
Changes to sharedState will also be passed to other components.
Source: https://skyronic.com/2016/01/03/vuex-basics-tutorial / Solution 2

Vue children Router: url changed but display parent component

I am learning Vue and stuck with nested router, I define some children router in the routes,but when I visit the child route it still display the parent component, my code is as following:
App.vue:
<template>
<div id="app">
<img src="./assets/logo.png">
<router-link :to="{name: 'Home'}">Home</router-link>
<router-link to="/cart">Cart</router-link>
<router-link to="/admin">Admin</router-link>
<router-link to="/admin/add">【Admin Add】</router-link>
<router-link to="/admin/edit">Admin Edit</router-link>
<router-view/>
</div>
</template>
<script>
export default {
name: 'app'
}
</script>
<style>
#app {
font-family: 'Avenir', Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>
Router/index.js:
import Vue from 'vue'
import Router from 'vue-router'
import Home from '#/components/pages/Home'
import Cart from '#/components/pages/Cart'
import Index from '#/components/pages/Admin/Index'
import Add from '#/components/pages/Admin/Add'
import Edit from '#/components/pages/Edit'
Vue.use(Router)
export default new Router({
routes: [
{
path: '/',
name: 'Home',
component: Home
},
{
path: '/cart',
name: 'Cart',
component: Cart
},
// {
// path: '/admin/index',
// name: 'Index',
// component: Index
// },
// {
// path: '/admin/add',
// name: 'Add',
// component: Add
// },
// {
// path: '/admin/edit',
// name: 'Edit',
// component: Edit
// }
{
path: '/admin',
// name: 'Admin',
component: Index,
children: [
{
path: 'add',
name: 'Add',
component: Add
},
{
path: 'edit',
name: 'Edit',
component: Edit
}
]
}
]
})
I tried not to use the children router, it will display the component correctly, just as the code which is commented.
I am so confused with this, please help me.
In your Index component you will need to add <router-view></router-view>. Check out this working example from the vue-router docs.
const User = {
template: `
<div class="user">
<h2>User {{ $route.params.id }}</h2>
<router-view></router-view>
</div>
`
}
const UserHome = { template: '<div>Home</div>' }
const UserProfile = { template: '<div>Profile</div>' }
const UserPosts = { template: '<div>Posts</div>' }
const router = new VueRouter({
routes: [
{ path: '/user/:id', component: User,
children: [
// UserHome will be rendered inside User's <router-view>
// when /user/:id is matched
{ path: '', component: UserHome },
// UserProfile will be rendered inside User's <router-view>
// when /user/:id/profile is matched
{ path: 'profile', component: UserProfile },
// UserPosts will be rendered inside User's <router-view>
// when /user/:id/posts is matched
{ path: 'posts', component: UserPosts }
]
}
]
})
const app = new Vue({ router }).$mount('#app')
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
<div id="app">
<p>
<router-link to="/user/foo">/user/foo</router-link>
<router-link to="/user/foo/profile">/user/foo/profile</router-link>
<router-link to="/user/foo/posts">/user/foo/posts</router-link>
</p>
<router-view></router-view>
</div>

VUEJS vue-router access router from nested routes

I have problem to access route object from nested views. Here is the simplified code:
main.js
import Vuetify from 'vuetify'
import VueRouter from 'vue-router'
import Vuetify from 'vuetify'
Vue.use(VueRouter)
Vue.use(Vuetify)
const router = new VueRouter({
routes : [
{path : '/contacts', component: Contacts,
children: [
{
path: ':id',
component: ContactDetails
}
]
},
],
mode: 'history'
})
new Vue({
el: '#app',
render: h => h(App),
router
})
ContactDetails.vue
<template>
<v-btn icon dark class="mr-3" #click.native="editContact">
<v-icon>edit</v-icon>
</v-btn>
</template>
<script>
export default {
data : () => ({
}),
methods: {
editContact: ()=>{
console.log('edit contact');
this.$router.go(-1) //this gives an error
}
},
}
</script>
It says "router is undefined", when I use
this.$router.go(-1)
from main routes (aka /contacts), it works. I tried all of the below code on the child:
router.go(-1)
$router.go(-1)
this.$router.go(-1)
this.router.go(-1)
this.$parent.$router.go(-1)
None of them works. Is there a way to reach to router object from nested routes? Or should I emit an event to parent and change view from there?
I have found an error in your code - it's in ()=>{...} function :)
Using an arrow function you are addressing ContactDetails-component this (object) and it does not contain any $router indeed. After you change an arrow function to function() {} your code will work as expected, because Vue rebinded to its instance where the $router is declared.
Now, lets look at this working copy (codepen) of your code:
Vue.use(VueRouter)
let ContactDetails = {
mounted() {
console.log('ContactDetails mounted...');
},
methods: {
editContact: function() {
console.log('edit contact');
this.$router.go(-1) //this DOES NOT give an error ANYMORE
}
},
template: `<button #click="editContact">edit</button>`,
}
let Contacts = {
components: {ContactDetails},
mounted() {
console.log('Contacts mounted...');
},
template: `Contacts... <ContactDetails></ContactDetails>`,
};
const router = new VueRouter({
mode: 'hash',
routes : [{
path : '/contacts',
component: Contacts,
children: [{
path: 'id',
component: ContactDetails
}]
}],
});
const vm = new Vue({
el: '#app',
components: {
Contacts,
ContactDetails,
},
router
});
vm.$router.push("/contacts/id");
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue-router/3.0.2/vue-router.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<router-view></router-view>
</div>

Categories

Resources