how to redirect to specific component in vue js - vue.js

I want to redirect inside a URL without page refresh, without using a router link as below :
<router-link to="/about us " active-class="active">foo</router-link>
I want to print routes like below:
<li class="nav-item phone">
<a class="nav-link" href="contact-us.html">
اتصل بنا
</a>
</li>
My route:
const routes = [
{ path: '/aboutus/', component: AboutUs }
]

Try this
this.$router.push('about')

You may need a workaround for this.
This solution won't change the url either :)
Set an html in the data
data: () => {
return {
html: null
}
}
Get the content of your html file using any request and assign to the html in data section. You can fetch this from any life cycle hook. Here I'm using beforeMount.
beforeMount() {
this.fetchAllEmployees();
axios.get('contact-us.html')
.then(response => {
this.html = response.data;
})
}
Now you can show the html content in your component like this
<template>
<div>
<div v-html="html"></div>
</div>
</template>
To show only when clicking the a tag, you can add another variable in the data which can be used to toggle the value.

Related

redirection link generate by the methods to href or nuxt-link

Hello I want to display a page with a link generated by a method.
Here is my current code.
<template>
<nuxt-link :to="seeProduct(item.sku.product.id).toString()">
<div>
<span>Go to product</span>
</div>
</nuxt-link>
</template>
<script>
export default {
methods: {
async seeProduct(id) {
const app = { $axios: this.$axios };
const urlProduct = await endPoint.getProduct(app, id);
console.log(urlProduct.url); // https://www.products/gants.html => this is the url
return urlProduct.url;
},
}
}
</script>
When I click on the link, the redirection is not good. How to do a good redirection with an URL generated by a method?
If it's an internal path, I do recommend you passing an actual path only or even better, a name as shown here: https://router.vuejs.org/guide/essentials/navigation.html#router-push-location-oncomplete-onabort
It should look something like :to="{ name: 'gants' }" when your seeProduct method is done.

How to have list + details pages based on API fetched content

I am facing a issue in my nuxt projct.
when i route the page by using nuxt-link, it doesn't render component in my page, i guess this is not making fetch call.
but when i use normal a href link, my page is working fine. everything is in place.
here is the link in a blog listing page component
// blog listing page snippet
<template>
<div>
<div v-for="blog in blogs.response.posts" :key="blog.id" class="col-md-3">
<nuxt-link :to="`/blogs/${blog.id}`" class="theme-blog-item-link"> Click to View Blog </nuxt-link>
</div>
</div>
</template>
<script>
export default {
data() {
return {
blogs: [],
}
},
async fetch() {
this.blogs = await fetch('https://www.happyvoyaging.com/api/blog/list?limit=4').then((res) => res.json())
},
}
</script>
but this works fine with if i replace nuxt-link with a href tag
<a :href="`/blogs/${blog.id}`" class="theme-blog-item-link">
Click to View Details
</a>
By click to that link, i want to view the detail of the blog by given id. that is _id.vue, code for that page is below.
//This is Specific Blog Details page code
<template>
<div class="theme-blog-post">
<div v-html="blogs.response.description" class="blogdesc"></div>
</div>
</template>
<script>
export default {
data(){
return {
blogs: []
}
},
async fetch() {
const blogid = this.$route.params.id
this.blogs = await fetch('https://www.happyvoyaging.com/api/blog/detail?id='+blogid+'').then((res) => res.json())
},
}
</script>
problem is on blogdetails page, where routing through nuxt-link not rendering the components but by normal a href link, it works fine
I am getting this error in console
vue.runtime.esm.js?2b0e:619 [Vue warn]: Unknown custom element: <PageNotFound> - did you register the component correctly? For recursive components, make sure to provide the "name" option.
found in
---> <Error> at layouts/error.vue
<Nuxt>
<Layouts/default.vue> at layouts/default.vue
<Root>
Since your API requires some CORS configuration, here is a simple solution with the JSONplaceholder API of a index + details list collection.
test.vue, pretty much the blog listing in your case
<template>
<div>
<div v-if="$fetchState.pending">Fetching data...</div>
<div v-else>
<div v-for="item in items" :key="item.id">
<nuxt-link :to="`/details/${item.id}`"> View item #{{ item.id }}</nuxt-link>
</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
items: [],
}
},
async fetch() {
const response = await fetch('https://jsonplaceholder.typicode.com/users')
this.items = await response.json()
},
}
</script>
details.vue, this one needs to be into a pages/details/_id.vue file to work
<template>
<div>
<button #click="$router.push('/test')">Go back to list</button>
<br />
<br />
<div v-if="$fetchState.pending">Fetching details...</div>
<div v-else>{{ details.email }}</div>
</div>
</template>
<script>
export default {
data() {
return {
details: {},
}
},
async fetch() {
const response = await fetch(`https://jsonplaceholder.typicode.com/users/${this.$route.params.id}`)
this.details = await response.json()
},
}
</script>
As you can see, I do only use async/await here and no then for consistency and clarity.
Try this example, then see for fixing the CORS issue. The latter is backend only and not anyhow related to Nuxt. A quick google search may give you plenty of results depending of your backend.

Component works only once using router-link - Laravel vue

I am working on a project that uses Laravel Vue SPA, and I got a problem accessing the data of the single product, it's only working when I click once, but when I select again with other product, I can't get the product data, but the URL is correct it's changes the ID but can't access the data.
It is working when I click another link like Services then select product, it can display the product data.
Here is my HTML
<ul >
<li v-for="product in products">
<router-link :to="{ name: 'edit-product', params: { id: product.id } }">
{{ product.title }}
</router-link>
</li>
</ul>
My Vue Routes
const EditProduct = require('./components/EditProduct').default;
{
path: '/edit/product/:id',
component: EditProduct,
name: 'edit-product'
}
my EditProduct component
<template>
<div>
<h1>this.$route.params.id</h1>
</div>
</template>
Cheers
Look at this answer. You have to watch the productId and execute your logic again.
Possible solution
try to define a computed property inside your EditProduct component for get product id
computed: {
productId(){
return this.$route.params.id
}
}
and use productId inside your <h1> tag
<template>
<div>
<h1>{{ productId }}</h1>
</div>
</template>
update
solution :
add this watcher to your EditProduct component for reacting with params change
watch: {
$route(to) {
console.log(to.params.id)
// you can call your method here and pass product id to them for example: this.getProductDetails(to.params.id)
},
beforeRouteEnter (to, from, next) {
next(vm => {
//also call your method here => vm.getProductDetails(to.params.id)
});
},
you can read more about params changes here: Reacting to Params Changes

Vue CLI clickable dynamic url from a news API

I'm fetching data from newsapi.org and I want there to be a clickable link after the headlines so that you can read more about the article. But I can't make it work.
Maybe this is too advanced for me since I'm no good at coding. I thought maybe there was a simple way of making the dynamic urls work.
<template>
<div class="api">
<h1>Latest gossip</h1>
<br />
<div v-for="item of items" v-bind:key="item.id">
<h3>{{ item.title }}</h3>
<p>{{ item.description }}</p>
<a v-bind:href="adress">
{{ item.url }}
</a>
</div>
</div>
</template>
I use axios.
<script>
import axios from "axios";
export default {
name: "Api",
props: ["articles"],
data() {
return {
items: [],
adress: "item.url"
};
},
mounted() {
this.getInfo();
},
methods: {
getInfo() {
axios({
method: "GET",
url:
"https://cors-anywhere.herokuapp.com/https://newsapi.org/v2/top-headlines?country=se&category=entertainment&apiKey=XXX",
dataType: "json",
headers: {
"X-Requested-With": "XMLHttpRequest",
"Access-Control-Allow-Origin": "*"
}
}).then(res => {
/* eslint-disable no-console */
console.log(res.data);
this.items = res.data.articles;
});
}
}
};
</script>
You can use vue-router in that case. You create a route with a parameter /news/:id in router/index.js eg.
const router = new VueRouter({
routes: [
{ path: '/news/:id', component: SingleNews }
]
})
then instead of
<a href=""/></a>
use
<router-link :to="{ name: 'news', params: { id: news.id }">{{news.headline}}</router-link>
And finally, retrieve parameter in a SingleNews.vue component using
this.$route.params.id
You can read more about vue-router and dynamic routes in the documentation https://router.vuejs.org/
So from what I understand, you're going to have a separate url for each different news article. It seems like there is a slight misunderstanding about how that information will be passed into the anchor tag, where it should be coming from, and how you're using data.
First, let's address your data method. If you look at the structure of your data you can see that you have an items property, which is an array and an adress property, which is set to a string.
data() {
return {
items: [],
adress: "item.url"
};
},
The problem here is that adress is not dynamic. It will always be the literal string "item.url", which is to say that it will always represent those characters ("item.url") in that order, but it doesn't actually represent any specific item's url property.
The good news is that you should already be seeing the correct url displayed on your page here:
<a v-bind:href="adress">
{{ item.url }}
</a>
Remember that an anchor tag in this case has two parts:
1. What we're displaying to the user.
2. Where we're telling the browser to redirect to.
The proper syntax here (without Vue) would be something like:
<a href="https://somelinktogoto.com">
Some text to display
</a>
What you're currently saying is: "I want an anchor tag to display the item's url to the user and redirect to whatever is stored in the data property called adress". Since adress is only storing the string "item.url", if you inspect your html that's been generated in your browser, I would suspect that all of your anchor tags look something like this:
<a href="item.url">
https://somenewsarticle.com
</a>
Luckily, the fix here is simple. Since you're already using v-bind, the href can use dynamic information, or information that's stored in your data somewhere, which can be referenced by its name. Then you can choose to display anything you'd like to your user. You can also delete your adress property from data, because it's not serving any purpose if all the urls are contained within items.
Try:
<a v-bind:href="item.url" target="_blank">
Read more...
</a>
data() {
return {
items: [],
}
}
Also, no one is good at coding at first, just keep trying to understand how data is flowing and you'll get there!
This line worked out great! Thank you!
<a v-bind:href="item.url" target="_blank">Read more here: </a>
I also deleted the adress data.

How to get route params to work with vue-router and vuex

I'm trying to pass data from a component to $route.params.post but somewhere along the line it's failing and I'm not sure how to get it to work.
In my component I'm using router-link to go to a specific path in my routes file but it's not routing to the specified component.
// Component.vue
<router-link :to="{ path: 'replies', params: { post: postId }}">
<div class="button is-light is-small has-replies" #click=" postId = thread.no ">Replies</div>
//clicking replies will push the thread number to data and load it into the params
</router-link>
export default {
data () {
return {
postId: null
}
}
}
// ./routes/index.js
import Replies from '../components/Replies'
routes: [
{ path: '/', component: Frontpage },
{ path: '/replies/:post', component: Replies }
]
Clicking the button should open the Replies component with the route looking like /replies/# but it's just loading a blank page and ignoring the component entirely. I'm importing vuex-router-sync on my main.js, but I can't tell if that's the issue, but I'm aware it very well may be since I'm not entirely sure I'm using vuex-router-sync correctly.
You can try it like following, as postId is not a URL parameter, but part of the URL itself:
<router-link :to="'replies/'+ postId'">
<div class="button is-light is-small has-replies" #click=" postId = thread.no ">Replies</div>
//clicking replies will push the thread number to data and load it into the params
</router-link>