I have simple menu tabs router as follow:
Tab 1 | Tab 2 | Tab 3
Routes are attached with individual component to each tab as example below.
const router = new VueRouter({
routes: [
{ path: '/views/type1', component: Type1, props: { listname: value} }
]
})
Problem:
How route[] prop modify to take the value from "data" of vue. Basically,
one of the component accept property as 'Array' and I need to pull those data from service and attach to component.
routes: [
{ path: '/views/type1', component: Type1, props: { collection: *[retrieve from service and attach here]*} }
]
//collection is not able to bind from "methods" or "data" , it only accepts static data.
The props field of Vue Router does not hold properties to be passed to the rendered view component, but rather it is a Boolean flag (or a hash/map of view names to Boolean flags) that tells Vue Router to pass any route parameters (parsed from the path) as properties to the component.
For example, given the following:
route config:
{
path: '/user/:name/:uid',
component: User,
props: true
}
User component definition:
export default {
props: ['name', 'uid']
}
URL:
/user/john/123
Then, User would be rendered with name set to john and uid set to 123, equivalent to this:
<User :name="john" :uid="123" />
If you need to initialize a view with server data, you could wrap the target component (e.g., with Type1View) that you initialize after you've fetched the data. In the example below, Type1.list is bound to a local list data variable. When Type1View mounts, we fetch data from the server, and save the result in list, which also updates Type1.list.
<template>
<div>
<Type1 :list="list" />
</div>
</template>
<script>
export default {
name: 'Type1View',
data() {
return {
list: []
}
},
async mounted() {
const data = await this.fetchData();
this.list = data.list;
}
}
</script>
Related
I want to pass data to another page and I use the following code:
this.$router.push({ path: '/guard/foreigner-list', params: data});
Then I expect item is equal to data, but item is null
let item = this.$route.params;
You did not posted the entire code that is related to the process of changing route. But according to Vue Router documentation:
params are ignored if a path is provided, which is not the case for query, as shown in the examples. Instead, you need to provide the name of the route or manually specify the whole path with any parameter
So if you have defined a route called user in your router.js file like below:
import User from "../views/User"
const routes = [
{
path: '/user/:id',
name: 'User',
component: User
}
]
Then you can navigate programmatically from Home.vue to User.vue with the codes below:
Home.vue:
<template>
<div class="home">
<button #click="navigFunc">click to navigate</button>
</div>
</template>
<script>
export default {
name: 'Home',
methods: {
navigFunc: function () {
const id = '123';
// using "name" not "path"
this.$router.push({ name: 'User', params: { id } });
}
}
}
</script>
User.vue:
<template>
<section>
<h1>User page</h1>
</section>
</template>
<script>
export default {
name: "User",
mounted() {
/* access the params like this */
console.log(this.$route.params)
}
}
</script>
<style scoped>
</style>
Notice that the variable I defined (id), is the same as the params that was defined in router.js (path: '/user/:id').
Start from vue-router#4.1.4 (2022-08-22) passing object through params is no longer a viable option, since it is consider as anti-pattern.
However,
there are multiple alternatives to this anti-pattern:
Putting the data in a store like pinia: this is relevant if the data is used across multiple pages
Move the data to an actual param by defining it on the route's path or pass it as query params: this is relevant if you have small pieces of data that can fit in the URL and should be preserved when reloading the page
Pass the data as state to save it to the History API state: ...
Pass it as a new property to to.meta during navigation guards: ...
I want to use the name of the component is dynamic, i have a component menu with navigation to another components, so i want to get name the same of the current route. I have this:
export default{
// name:'app',
name: 'Dynamic name follow router name',
data(){
return{}
}
}
Note: name of component the same of current route. I have two router, but it link to the same page.
I tried this code below:
export default{
name: '',// How can i use dynamic this name
data(){
return{}
},
created(){
this.$options.name = this.$route.name
this.getData()
},
methods:{
function getData(){
// Statement
}
}
}
My purpose
I want to keep-alive data from router when i change page
What I want is when I click an image, it redirects to a URL (another view) which is made by the something/image_name. I am making the project in vue.js. I am thinking of doing this by using props (passing all the variables needed from the first view to the next view). But the data is not displayed in the 2nd view. Also, I want to know how can I make the URL like something/image_name. I am using it by hardcoding the URL.
routes.js
const router = new Router({
mode: "foo",
base: "foobar",
routes: [
{
path: "/event/:title",
name: "event",
component: event,
props: true,
}
where title is the variable (event.title to be more precise) I want to pass from other view. I also want to get title in URL also.
view 1
<template>
<div src="image_location" :to="/event/{{event.title}}"></div>
</template>
<script>
export default {
name: "event",
components: {
Event
},
data: function initData() {
return {
event: {},
};
},
};
</script>
view 2 (Event.vue) (its URL should be foobar/event/{{ title }})
props: {
event: Object,
}
I tried router-link also but lack of its documentation restricts me from using it efficiently.
You can add an #click event to the image and programmatically move the user to the new URL when they click on the image. Something like:
<imge src="..." #click="$router.push(`/event/${event.title}`)" />
I am researching whether a vue router is the best approach for the following scenario:
I have a page containing 'n' number of divs. Each of the divs have different content inside them. When a user clicks on a button in the div, I would like the div to open in a separate browser window (including its contents).
Can a route name/component be created on the fly to route to? Since I have 'n' number of divs, that are created dynamically, I cannot hard-code name/components for each one
<router-link :to="{ name: 'fooRoute'}" target="_blank">
Link Text
</router-link>
I want to avoid the same component instance being used (via route with params) since I may want multiple divs to be open at the same time (each one in their own browser window)
If the link is opening in a separate window, it makes no sense to use a <router-link> component as the application will load from scratch in any case. You can use an anchor element instead and generate the href property dynamically for each div.
To answer your questions:
A route name cannot be created dynamically since all routes must be defined at the beginning, when the app (along with router) is being initialized. That said, you can have a dynamic route and then dynamically generate different paths that will be matched by that route.
There is no way for the same component instance to be reused if it's running in a separate browser window/tab.
It is possible to create dynamic router name.
profileList.vue
<template>
<main>
<b-container>
<b-card
v-for="username in ['a', 'b']"
:key="username"
>
<b-link :to="{ name: profileType + 'Profile', params: { [profileType + 'name']: username }}">Details</b-link>
</b-container>
</main>
</template>
<script>
export default {
name: 'profileList',
data () {
return {
profileType: ''
}
},
watch: {
// Call again the method if the route changes.
'$route': function () {
this.whatPageLoaded()
}
},
created () {
this.whatPageLoaded()
},
methods: {
whatPageLoaded () {
this.profileType = this.$route.path // /user or /place
}
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style>
</style>
b-container, b-card, b-link are taken from bootstrap-vue, so you can freely change it.
router.js
const router = new Router({
mode: 'hash',
base: process.env.BASE_URL,
linkExactActiveClass: 'active',
routes: [
// USERS
{
path: '/user/:username',
name: userProfile,
component: userProfile
},
{
path: '/user',
name: 'userList',
component: profileList
},
// PLACES
{
path: '/place/:placename',
name: placeProfile,
component: placeProfile
},
{
path: '/place',
name: 'placeList',
component: ProfileList
}
]
})
In VueJS 2 with vue-router 2 I am using a parent view with subcomponents like this:
WidgetContainer.vue with route /widget_container/:
<template>
<component :is="activeComponent"></component>
</template>
<script>
import WidgetA from './components/WidgetA'
import WidgetB from './components/WidgetB'
export default {
name: 'WidgetContainer',
components: {
WidgetA,
WidgetB
},
data () {
return {
activeComponent: 'widget-a'
}
}
}
</script>
In WidgetA I have the option of selecting a widget id
<template>
// v-for list logic here..
<router-link :to="{ path: '/widget_container/' + widget.id }"><span>{{widget.name}} </span></router-link>
</template>
<script>
export default {
name: 'WidgetA',
data() {
return {
widgets: [
{ id: 1,
name: 'blue-widget'
}]}}
routes.js:
export default new Router({
routes: [
{
path: '/widget_container',
component: WidgetContaner
},
{
path: '/widget_container/:id?',
redirect: to => {
const { params } = to
if (params.id) {
return '/widget_contaner/:id'
} else {
return '/widget_container'
}
}
}]})
From the WidgetContainer if the route is /widget_container/1 (where '1' is the id selected in WidgetA) I want to render WidgetB, but I cant work out:
1) how to pass the selected widget id into the router-link in WidgetA
2) How to know in WidgetContainer the the route is /widget_contaner/1 instead of /widget_container/ and render WidgetB accordingly.
Any ideas?
You can pass data to parent using by emitting event, you can see more details around here and here.
Once the data is change, you can watch over it and update the variable which has stored your widget.
Another option, if communication between components become unmanageable over time is to use some central state management, like vuex, more details can be found here.
Wouldn't it be easier and more scallable to use Vuex for that?
Just commit id to store and than navigate ?