Vuejs Displaying a component multiple times with Axios in it - laravel

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>

Related

how to get each data from response api laravel in vue js 3

Need help , i can get all data from response api but having some problem when try to get data (looping data ) from key "get_item_cards" . Here's my response and code in vue js
Response api
<script setup>
<script>
import axios from 'axios'
export default {
name: 'ListNotes',
data() {
return {
cardNotes: [],
}
},
mounted() {
// console.log('Page mounted');
this.getListNotes();
},
methods: {
getListNotes() {
axios.get('http://localhost:8000/api/card').then(res => {
this.cardNotes = res.data.cardNotes
console.log(this.cardNotes);
})
}
}
}
</script>
how the best way to get all data & each data from relationship in vue js 3
Since the this.cardNote returns an array with three elements, you can use loop using v-for and access to the get_item_cards array like below,
<template>
<div>
<div v-for=(note, index) in cardNote>
<p>{{node.cardname}}</p>
<div v-for=(item, key) in note.get_item_cards>
<p>{{item.content}}</p>
</div>
</div>
</div>
</template>
<script setup>
<script>
import axios from 'axios'
export default {
name: 'ListNotes',
data() {
return {
cardNotes: [],
}
},
mounted() {
// console.log('Page mounted');
this.getListNotes();
},
methods: {
getListNotes() {
axios.get('http://localhost:8000/api/card').then(res => {
this.cardNotes = res.data.cardNotes
console.log(this.cardNotes);
})
}
}
}
</script>

Laravel vue.js and vuex link body text by id and show in a new component

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.

owl.carousel vue.js component not rendering in lavarel application

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;
});
},
}

How to transfer data between components placed in different views

I have two compoennts placed in one the same view.
#extends('layouts.app')
#section('content')
<bus></bus>
<bus2></bus2>
#endsection
I want to pass data (name) from one component to other one after clicking button. To do that I' using $emit function.
/// bus component
<template>
<div>
<p> Name Bus 1{{name}}</p>
<input type="button" #click="setName()" value="s"/>
</div>
</template>
<script>
export default {
created() {},
data: function() {
return {
name: "Volvo"
};
},
methods: {
setName: function(id) {
this.$root.$emit("sname", this.name);
}
},
props: []
};
</script>
///bus 2 component
<template>
<div>
<p> Name bus 2{{name}}</p>
</div>
</template>
<script>
export default {
created() {
this.$root.$on("sname", data => {
this.name = data;
});
},
data: function() {
return {
count: 0,
name: ""
};
},
methods: {}
};
</script>
Everything works fine. Name is transfered from bus to bus2. The problem exists when I place bus2 in different view - data are not transfered but code is the same. How can I transfer data between components placed in different views
Try using Vuex to specify your app state, and mutate this when it's necessary.
Vuex states are accessible from every components using this.$store or $store.

dusk test about continuity click(double click) without waiting backend process

I am testing the following due with laravel dusk.
Vue component purpose is disable continuity click by user to avoid registering duplicate data.
The test I want to implement is fast continuity click by user.
But after
$browser->assertSourceHas($buttonEnableSource)
->click('#submit-button-component')
Test will wait for browser process.
So if I write down the following, it will make error that has no applicable Vue.
$browser->assertSourceHas($buttonEnableSource)
->click('#submit-button-component')
->click('#submit-button-component')
Is there a way to implement fast continuity click by user with dusk?
The following is the source code.
<template>
<div>
<input type="submit" class="button_orange button_big" :value="value" v-show="!isSubmitting" #click="startSubmit">
<div class="button_white button_big" v-show="isSubmitting">{{ value }}</div>
</div>
</template>
<script>
export default {
data() {
return {
isSubmitting: false,
};
},
props: {
value: {
type: String,
default: '',
},
},
methods: {
startSubmit() {
this.isSubmitting = true;
},
},
};
</script>
public function testRegisterDoubleClickNoDuplication()
{
$this->browse(function (Browser $browser) {
$buttonValue = __('common.register');
$buttonEnableSource = "<input type=\"submit\" class=\"button_orange button_big\" value=\"{$buttonValue}\" />";
$browser->visit(route('staffs.create'))
->assertSourceHas($buttonEnableSource)
->click('#submit-button-component')
->assertSourceMissing($buttonEnableSource)
->assertSee('スタッフ詳細');
});
}

Resources