Load a VUE component with parameters - javascript

I have
<a role="button" v-on:click="setMemberName(item)">
And it calls a method:
methods:{
setMemberName(item) {
alert(item.email);
this.$router.push('about');
}
},
The alert gets fired and the router gets called but I need to send the parameter of item.email and I need to capture that when the 'about' vue gets loaded. I have a simple alert being called using:
,
mounted:function () {
alert("Hello");
},
But I would like it to say "Hello " then the email address like "Hello Smith#jmail.com". I really need the email address so I can call a webservice but Hello is fine for this problem. As you can tell VUE is new to me.
I have tried:
this.$router.push({ name: 'about', params: { itemEmail: item.email } })
but it seems that it never loads the 'about' vue. Thanks for the help.
OK-- edit-- It does get fired if I use the proper case 'About' instead or 'about' but I still need help on the capture side
Code for the about vue: a simple div and some script code:
<script>
export default {
name: 'About',
data() {
return {
}
},
methods:{
},
mounted:function () {
alert("Hello");
},
created(){
},
}
</script>

There are many ways of solving this issue, your are using route params so you need to define the param in the route:
routes: [
{ path: '/about/:email', component: About }
]
Then you can access the param in the About component
In the template:
<div>Email: {{ $route.params.email }}</div>
In the script:
sayHello() {
alert($route.params.email);
}
Note that you could also use route query params or route props, read the docs at: https://router.vuejs.org/guide/

If you update your push to (see docs for full options):
this.$router.push({ name: 'about', query: { itemEmail: item.email } })
You can access the query parameters (See docs here):
this.$router.query.itemEmail

Related

Redirect to 404 page without modifying the URL in Vue.js

In my Vue.js project, I want to display my 404 page, if a route parameter is invalid. For now, I'm using the following code for that:
this.$router.replace({ path: '/404' });
Is there a way to do that without modifying the URL? I want the user to still be able to copy the browser's original URL line. Is there some kind of a silent: true parameter?
With vue-router, the URL is the source of truth. If the URL changes, so does the rendering. You can't "pause" the router. (This is a flaw in vue-router that has been bugging me for ages, but I digress.)
You just have to display the 404 page without modifying the route. Have some display404 data property in your root component that you can set to display the 404 page manually in the template instead of the <router-view>, e.g:
<div>
<my-404-page v-if="display404"/>
<router-view v-else/>
</div>
To display the 404 page from any component:
this.$root.display404 = true
Of course this is just a basic example to demonstrate what I mean, you might want to use Vuex to share the state, or use an event bus, or you can display the 404 page in some other way that works for you, etc.
This was fixed in Vue Router 4 which you can see on the second example in the docs.
Build your NotFound route like this:
{
path: '/:pathMatch(.*)*',
name: 'NotFound',
component: NotFound
},
Then you can use a beforeEnter navigation guard on your dynamic Vue like so:
// In your router/index.js file...
{
path: 'users/:id',
name: 'User Detail',
component: UserDetail,
beforeEnter(to, from) {
// See if that query exists in your data...
const exists = data.users.find(
user => user.id === parseInt(to.params.id)
)
if (!exists) {
// THE IMPORTANT PART
// Return your not found view...
return {
name: 'NotFound',
// Match the path of your current page and keep the same url...
params: { pathMatch: to.path.split('/').slice(1) },
// ...and the same query and hash.
query: to.query,
hash: to.hash,
}
}
}
}
Haven't tested this in a Component yet, but I'd assume it'd be the same logic in the beforeRouteEnter navigation guard.
Not 100% sure what you are asking, but is either of these any help?
A catch all route:
From Vue.js docs "Catch all route"
Or if you are managing a response form a call (method/fetch/ etc): Use a combination of try/catch and a "loading" data value to change the display or what component is loaded.
Based on Decade Moon's solution, I did the following:
main.js
import Error404 from './views/error/404.vue'
Vue.component('error-404', Error404)
404.vue
<template>
<div>
<h1>Page not found</h1>
<p>Whatever...</p>
</div>
</template>
<script>
export default {
name: 'Page not found'
}
</script>
router --> index.js
const PageNotFound = () => import('#/views/error/404')
function configRoutes() {
return [
{
path: '/',
name: 'Home',
component: TheContainer,
children: [
// ...
{
path: '404',
name: 'Page not found',
component: PageNotFound,
alias: '*'
}
]
}
]
}
My Page which should display the 404 error
<template>
<div class="animated fadeIn" v-if="clientSettings">
...
</div>
<error-404 v-else></error-404>
</template>
<script>
export default {
name: 'Test',
data() {
return {
clientSettings: null
};
},
async created() {
this.setClientConfig();
},
watch: {
'$route.params.id': function (id) { this.setClientConfig(id);}
},
methods: {
setClientConfig(id) {
if (!id) {
id = this.$route.params.id;
// Redirect to the first valid list, if no parameter is proviced
if (!id) {
this.$router.push({ name: 'Test', params: { id: this.$root.clientConfiguration[0].name } });
return;
}
}
// Set client settings
this.clientSettings = this.$root.clientConfiguration.find(cc => cc.name === id);
// This will return null, if no entry was found, therefore the template will jump into the v-else
}
}
}
</script>

Force to use window.location.href in vue-router hash mode

I'm using vue-router 3.0.1, and the mode is hash.
The current url is:
/#/?type=1
I tried to use window.location.href for the same path, but different query parameter like this.
window.location.href = '/#/?type=2';
But the url of the browser changes, but nothing else happens.
At the first place, I am trying this, because router.push didn't re-render the component.
The original window.location.href should give the different result, but vue-router looks like to override window.location.href.
How can I force to move to /#/?type=2, in this case?
You don't need to use window.location.href to make it work. The problem here is that the component is reused when you only update the query parameter and the component will not automatically re-render. One way to solve this issue is to watch the $route in your component. Here's an code example. You also can find the jsFiddle here https://jsfiddle.net/Fourzero/cbnom5sL/22/.
Html
<script src="https://npmcdn.com/vue/dist/vue.js"></script>
<script src="https://npmcdn.com/vue-router/dist/vue-router.js"></script>
<div id="app">
<!-- You can use router-link to trigger the url change or router.push in your code -- it doesn't matter. -->
<router-link to="/?type=2">type 2</router-link>
<router-link to="/?type=1">type 1</router-link>
<router-view></router-view>
</div>
JavaScript
const Bar = {
template: '<div>Type {{type}}</div>',
data () {
return {
type: ''
}
},
mounted () {
this.type = this.$route.query.type;
},
watch: {
$route(to, from) {
// Update the data type when the route changes.
this.type = to.query.type;
}
}
}
const router = new VueRouter({
mode: 'hash',
routes: [
{ path: '', component: Bar },
]
})
new Vue({
router,
el: '#app',
data: {
msg: 'Hello World'
}
})
For detailed explanation, you can refer the official doc https://router.vuejs.org/guide/essentials/dynamic-matching.html.

How to redirect in Vue.js to different url when clicked?

I'm making a post board with Vue.js and trying to make the page redirected when each post is clicked.
I've installed vue-route and axios.
In index.js,
export default new Router({
route: [
{
path: '/',
name: 'Post',
component: Post
},
{
path: '/:req_no',
name: 'Detail',
component: Detail
},
]
})
In post.vue
<div #click="detailPost(post.no)">{{post.title}}</div>
.
.
.
detailPost(req_no) {
this.$router.push({
path: `https://dataURL/detail.php/${req_no}`
})
}
In Detail.vue
<template>
<div>
{{contents}}
</div>
</template>
<script>
import axios from 'axios';
export default {
name: 'Datail',
data() {
return {
req_no: this.$route.params.req_no,
contents: {}
}
},
created() {
axios.get('https://dataURL/detail.php/', {
params: {
req_no: this.req_no
}
}).then(res => {
this.contents = this.res.data
});
}
}
</script>
I'm not sure where to put the url (in the function in post.Vue, detailPost() or in Detail.vue)
If I put it in the function, I get
http://localhost:8080/#/http://dataURL/detail.php/2
The API guide says I must use the params.
Could you please help me where to fix? Thanks alot!!
You cannot use the router for a different domain.
See this answer: https://stackoverflow.com/a/41654493/146656
What you can do is simply use vanilla JS to do it:
window.location = `https://dataURL/detail.php/${req_no}`;
Is https://dataURL/detail.php on same domain with your main app?
Please try:
this.$router.push({
path: `/detail.php/${req_no}`
})
If it's different domain, you can use window.location
window.location = https://dataURL/detail.php/${req_no};

Vuejs route based on payload

Im using vuerouter and want to route to a component based on payload.
{
path: '/foobar',
name: 'foobar',
component: foobar,
}
{
path: '/foobar',
name: 'foobarSuccess',
component: foobarSuccess,
query: { status: 'success' }
}
Example above, first route is step one. We do some stuff there then we go to another page and get redirected back with the payload status=succcess. How do i use the query object to route to the correct component?
You have to define your router with parameters
{
path: '/foobar',
name: 'foobar',
component: foobar,
}
{
path: '/foobar/:status',
name: 'foobarSuccess',
component: foobarSuccess,
query: { status: 'success' }
}
here status will contain like success, finally /foobar/success
based on this parameter also you can display the sccuess message
For more information you can refer the simple docs https://router.vuejs.org/en/essentials/dynamic-matching.html ,

How to get the latest data from parent to child components after page refresh

I am working on a project and using Vue.js for the frontend. I have following code in the main.js file.
new Vue({ // eslint-disable-line no-new
//el: '#app',
router,
data () {
return {
friends: []
}
},
methods: {
getFriends: function () {
return this.friends;
}
},
created: function () {
this.$http.get('/user/' + this.getUserIDCookie('userID') +
'/friends').then(function (response) {
this.friends = response.data;
});
},
components: {
'nav-bar': require('./components/Navigation.vue')
},
template: `
<div id="app">
<nav-bar></nav-bar>
<router-view class="router-view"></router-view>
</div>`
}).$mount('#app');
In one of the pages(for ex. when the page is redirected to localhost/#/user/1/details, I am retrieving the friends' list from main.js like below:
<script type="text/babel">
export default {
name: 'profile',
data: function () {
return {
user: {},
friends: []
}
},
methods: {
// Some methods
},
created: function () {
this.friends = this.$root.getFriends();
}
}
</script>
The problem arises when I refresh the current page. After page refresh, this.friends is null/undefined because this.$root.getFriends() is returning null/undefined. I can move it to user component, but I want to keep it in main.js so that GET call is used once and data will be available to the whole application.
Any input regarding how to solve this issue would be great. I am using Vue 2.0.1
Really, what you want to do, is pass the data the component needs as props.
The dirt simple easiest way to do it is this.
<router-view class="router-view" :friends="friends"></router-view>
And in your profile component,
export default {
props:["friends"],
name: 'profile',
data: function () {
return {
user: {},
friends: []
}
},
methods: {
// Some methods
}
}
If you want to get more sophisticated, the later versions of VueRouter allow you to pass properties to routes in several ways.
Finally, there's always Vuex or some other state management tool if your application gets complex enough.
The problem is that when you refresh the page, the whole app reloads, which includes the get, which is asynchronous. The router figures out that it needs to render details, so that component loads, and calls getFriends, but the asynchronous get hasn't finished.
You could work around this by saving and pulling the Promise from the get, but Bert's answer is correct: the Vue Way is to send data as props, not to have children pull it from parents.

Categories