I've been hunting and trying for the last handful of days but with no success.
I am trying to render a list of quotes to be displayed as a carousal on a login page.
I need to pull a list of quotes from a database which i have done. I then need to loop through the quotes and display them in the owl.carousel.
If i manually add the div.elements, it renders without a problem. when i add the element in a v-for loop, it does not display. Can someone please advise or guide me into the correct direction?
<template>
<carousel class="crsl" :autoplay="true" :nav="false" :items="1">
<div v-for="(item, index) in quotes" :key="item.id" v-text="item.quote"></div>
</carousel>
import carousel from 'vue-owl-carousel';
export default {
components: { carousel },
mounted() {
console.log('Component mounted.')
axios.post('api/quotes', {})
.then(response => {
this.quotes = response.data;
});
},
data: function () {
return {
quotes: null,
}
},
}
found a solution here
https://github.com/93gaurav93/v-owl-carousel/issues/16
My final code is as follows
<template>
<div v-if="quotes.length > 0">
<carousel :items="1" :autoplay="true" :nav="false" :dots="false">
<div v-for="(item, index) in quotes">
<div v-text="item.quote"></div>
</div>
</carousel>
</div>
<script>
import carousel from 'vue-owl-carousel';
export default {
components: { carousel },
data() {
return {
quotes: [],
};
},
mounted() {
axios.post('/api/quotes')
.then(resp => {
this.quotes = resp.data;
});
},
}
Related
I am very new to Laravel and Vuex, I have a simple array of post on my page.
test 1
test 2
test 3
I am trying to link the text on the AppPost.vue component and show the post that has been clicked on a new component (AppShowpost.vue) on the same page. I believe I have to get the post by id and change the state? any help would be good. Thank you.
when you click test 1 it will show "test 1" on a new component (AppShowpost.vue)
In side my store timeline.js, I belive I need to get the post by id and change the state ?
import axios from 'axios'
export default {
namespaced: true,
state: {
posts: []
},
getters: {
posts (state) {
return state.posts
}
},
mutations: {
PUSH_POSTS (state, data) {
state.posts.push(...data)
}
},
actions: {
async getPosts ({ commit }) {
let response = await axios.get('timeline')
commit('PUSH_POSTS', response.data.data)
}
}
}
My AppTimeline.vue component
<template>
<div>
<app-post
v-for="post in posts"
:key="post.id"
:post="post"
/>
</div>
</template>
<script>
import { mapGetters, mapActions } from 'vuex'
export default {
computed: {
...mapGetters({
posts: 'timeline/posts'
})
},
methods: {
...mapActions({
getPosts: 'timeline/getPosts'
})
},
mounted () {
this.getPosts()
}
}
</script>
My AppPost.vue component. I need to link the post.body to display the post in my AppShowpost.vue component.
<template>
<div class="w-full inline-block p-4">
<div class="flex w-full">
<p>
{{ post.body }}
</p>
</div>
</div>
</template>
<script>
export default {
props: {
post: {
required: true,
type: Object
}
}
}
</script>
My AppSowpost.vue component that needs to display the post that is clicked.
<template>
<div>
// Displaypost ?
</div>
</template>
<script>
export default {
// Get post from id ?
}
</script>
Okay you can create a new state in your vuex "current_state", asyou said, you can dispatch a mutation by passing the id to the vuex.
state: {
posts: [],
current_state_id : null
},
In your mutations
set_state_id (state, data) {
state.current_state_id = data;
}
On your app post.vue, you can set a computed property that watches the current state
computed: {
currentState() {
return this.$store.getters["timeline/current_state_id"];
}}
And create a watcher for the computed property to display the current id/post
watch: {
currentState: function(val) {
console.log(val);
},
Maybe this will help you. First I will recommend to use router-link. Read about router link here if your interested. It is very helpful and easy to use. But you will have to define the url and pass parameter on our vue-route(see bellow).
1.You can wrap your post.body in router-link as follow.
//With this approach, you don't need any function in methods
<router-link :to="'/posts/show/' + post.id">
{{ post.body }}
</router-link>
2. In your AppSowpost.vue component, you can find the post in vuex state based on url params as follow.
<template>
<div> {{ thisPost.body }} </div>
</template>
// ****************
computed: {
...mapState({ posts: state=>state.posts }),
// Let's get our single post with the help of url parameter passed on our url
thisPost() { return this.posts.find(p => p.id == this.$route.params.id) || {}; }
},
mounted() { this.$store.dispatch("getPosts");}
3. Let's define our vue route.
path: "posts/show/:id",
name: "showpost",
params: true, // Make sure the params is set to true
component: () => import("#/Components/AppShowPost.vue"),
Your Mutations should look as simple as this.
mutations: {
PUSH_POSTS (state, data) {
state.posts = data;
}
},
Please let me know how it goes.
i am using laravel-vue-pagination package for pagination on my laravel vuejs project.but when i click the next page it's not rendering and going to the page no.first page is loading fine.how can i go to the page number 2? here is the code. is another component.i did it accroding to the documentation.still it's not working.
<template>
<!-- Blog Comment threats -->
<div>
<h3>Comments (4)</h3>
<ul class="commentlist">
<comment :comments="comments.data"></comment>
</ul>
<pagination :data="comments" #pagination-change-page="getResults"></pagination>
</div>
<div>
</div>
<!-- blog comments form -->
<new-comment></new-comment>
<script>
import newComment from "./newComment.vue";
import Comment from "./Comment.vue"
export default {
components: {newComment, Comment},
props: ['post'],
data() {
return {
comments: {},
}
},
mounted() {
// Fetch initial results
this.getResults();
},
methods: {
getResults(page = 1) {
axios.get(`/api/post/${this.post}/comment?page=' + page`)
.then(response => {
this.comments = response.data;
});
},
},
}
So I have this code:
<template>
<div id="search-wrapper">
<div>
<input
id="search_input"
ref="autocomplete"
placeholder="Search"
class="search-location"
onfocus="value = ''"
#keyup.enter.native="displayPic"
>
</div>
</div>
</template>
<script>
import VueGoogleAutocomplete from "vue-google-autocomplete";
export default {
data: function() {
return {
search_input: {},
pic: {}
};
},
mounted() {
this.autocomplete = new google.maps.places.Autocomplete(
this.$refs.autocomplete
);
this.autocomplete.addListener("place_changed", () => {
let place = this.autocomplete.getPlace();
if (place.photos) {
place.photos.forEach(photo => {
let pic=place.photos[0].getUrl()
console.log(pic);
});
}
});
},
methods: {
displayPic(ref){
this.autocomplete = new google.maps.places.Autocomplete(
this.$refs.autocomplete);
this.autocomplete.addListener("place_changed", () => {
let place = this.autocomplete.getPlace();
if (place.photos) {
place.photos.forEach(photo => {
let pic=place.photos[0].getUrl()
console.log(pic);
});
}
})
},
}
}
I want to pass the "pic" parameter, resulted in displayPic, which is a function, into my template, after one of the locations is being selected.
I've tried several approaches, but I'm very new to Vue so it's a little bit tricky, at least until I'll understand how the components go.
Right now, the event is on enter, but I would like it to be triggered when a place is selected.
Any ideas how can I do that?
Right now, the most important thing is getting the pic value into my template.
<template>
<div id="search-wrapper">
<div>
<input style="width:500px;"
id="search_input"
ref="autocomplete"
placeholder="Search"
class="search-location"
onfocus="value = ''"
v-on:keyup.enter="displayPic"
#onclick="displayPic"
>
<img style="width:500px;;margin:5%;" :src="pic" >
</div>
</div>
</template>
<script>
import VueGoogleAutocomplete from "vue-google-autocomplete";
export default {
data: function() {
return {
search_input: {},
pic:""
};
},
mounted() {
this.autocomplete = new google.maps.places.Autocomplete(
this.$refs.autocomplete,
{componentRestrictions: {country: "us"}}
);
},
methods: {
displayPic: function(){
this.autocomplete.addListener("place_changed", () => {
let place = this.autocomplete.getPlace();
if (place.photos) {
place.photos.forEach(photo => {
this.pic=place.photos[0].getUrl()
});
}
})
},
}
}
</script>
I have been trying to figure out this for a hours but no luck. I have 2 components. The first component is dynamic and the second component just gets the user geolocation. The geolocation is then displayed in the first component.
My problem is that I display the first component a few times on the page and every time it is displayed it makes a GET request which is inefficient . If I display the component 3 times it will make 3 GET requests.
What would be the best way to rewrite this?
Thanks for the help
Component 1:
<template>
<section id="under-info">
THe user is from <ip_info></ip_info>
</section>
</template>
<script>
export default {
}
</script>
Component 2:
<template>
<span id="user-city">
{{value}}
</span>
</template>
<script>
export default {
mounted: function () {
this.$nextTick(function () {
this.getIpInfo(this.param)
})
},
props:['param'],
data: function () {
return {
value:null
}
},
methods:{
getIpInfo(){
var vm = this
delete axios.defaults.headers.common["X-Requested-With"];
delete axios.defaults.headers.common["X-CSRF-TOKEN"];
axios
.get('http://api.ipstack.com/check?access_key=?',{
timeout: 1000
})
.then(function(response) {
vm.value = response.data['city]
})
}
},
}
</script>
Wrap the code where you want to reuse this value 3x in a component.
<template>
<div>
The user is from {{location}}, and {{location}} is a great place. They have a baseball team in {{location}}
</div>
</template>
<script>
export default {
mounted: function () {
this.$nextTick(function () {
if(this.needLocation){
this.getIpInfo(this.param)
}
})
},
props:['param', 'needLocation'],
data: function () {
return {
location:null
}
},
methods:{
getIpInfo(){
this.location = //results from your API call
}
}
</script>
I am trying to fetch results from database in News.vue, and display them in Topnews.vue. I have two links fetched. When I click link1, it shows up the Topnews.vue template with everything working as intended, however, if i click link2, nothing happens, except for that the URL changes, but the template does not show up the result. If i refresh the page and click link2 or click on the navbar, then link2, it shows up, and same, clicking then link1, changes the URL, but doesnt show up. I'm really stuck on that and I'd be really glad if you help me out on that issue. Hope you understand.
News.vue
<template id="news">
<div class="col-sm-5">
<div class="cars" v-for="row in filteredNews" >
<div class="name" >
<p class="desc_top_time">{{row.created_at}}</p>
<span class="last_p"> {{row.category}}</span>
<h3 style="margin-bottom:-4px; font-size: 16px;">
<router-link class="btn btn-primary" v-bind:to="{name: 'Topnews', params: {id: row.id} }">{{row.title}}</router-link></h3>
</div></div></div>
</template>
<script>
export default {
data: function() {
return {
news: [],
}
},
created: function() {
let uri = '/news';
Axios.get(uri).then((response) => {
this.news = response.data;
});
},
computed: {
filteredNews: function() {
if (this.news.length) {
return this.news;
}
}
}
}
</script>
Topnews.vue
<template id="topnews1">
<div class="col-sm-7">
<div class="cars">
<img :src="topnews.thumb" class="img-responsive" width=100%/>
<div class="name" ><h3>{{ topnews.title }}</h3>
<p>
<br>{{ topnews.info }}<br/>
</p>
</div></div></div>
</template>
<script>
export default {
data:function(){
return {topnews: {title: '', thumb: '', info: ''}}
},
created:function() {
let uri = '/news/'+this.$route.params.id;
Axios.get(uri).then((response) => {
this.topnews = response.data;
});
}
}
</script>
Like GoogleMac said Vue will reuse the same component whenever possible. Since the route for both IDs use the same component Vue will not recreate it, so the created() method is only being called on the first page. You'll need to use the routers beforeRouteUpdate to capture the route change and update the data.
in TopNews.vue:
export default {
data:function(){
return {topnews: {title: '', thumb: '', info: ''}}
},
beforeRouteEnter:function(to, from, next) {
let uri = '/news/'+ to.params.id;
Axios.get(uri).then((response) => {
next(vm => {
vm.setData(response.data)
})
});
},
beforeRouteUpdate: function(to, from, next) {
let uri = '/news/'+ to.params.id;
Axios.get(uri).then((response) => {
this.setData(response.data);
next();
});
},
methods: {
setData(data) {
this.topnews = data
}
}
}
If you click a link referring to the page you are on, nothing will change. Vue Router is smart enough to not make any changes.
My guess is that the IDs are messed up. If you are using Vue devtools you will be able to easily see what data is in each link. Are they as you expect.