I have 2 vue-selects one of users and one of addresses. I need to get the id of what I select so i can send the id to my axios request where I need to compare if User has more than one address and show all of these addresses. I know I need to use v-model on the parent and from the child emit the event but then I'm getting confused how I actually get the id.
Parent component
<template>
<div>
<search-infinite
:url="'users'"
:label="'name'"
v-model:selectedUser="selectedUser"
>
</search-infinite>
<search-infinite
:url="'address'"
:label="'address'"
v-model:selectedAddress="selectedAddress"
>
</search-infinite>
</div>
</template>
<script>
import SearchInfinite from "./SearchInfinite";
export default {
name: "Home",
props:{
},
data: () => ({
url: String,
label: String,
selectedUser: "",
selectedAddress:"",
}),
components:{
SearchInfinite
},
methods:{
}
}
</script>
<template>
<v-select
:options="list"
:label="label"
:filterable="false"
@open="onOpen"
@close="onClose"
@search="inputSearch"
:loading="loading"
>
<template #list-footer>
<li v-show="hasNextPage" ref="load" >
Loading more options...
</li>
</template>
</v-select>
</template>
<script>
import 'vue-select/dist/vue-select.css';
import _ from "lodash";
export default {
name: 'Search-Infinite',
props:{
url: String,
label: String,
selectedAddress:null,
selectedUser:null,
},
data: () => ({
observer: null,
limit: 10,
search: '',
list: [],
total: 0,
page: 0,
loading: false,
}),
computed: {
hasNextPage() {
return this.list.length < this.total
},
},
mounted() {
this.observer = new IntersectionObserver(this.infiniteScroll)
},
created() {
this.getUsers();
},
methods: {
getUsers(search) {
this.page ;
axios
.get(this.url, {
params: {
search: search,
page: this.page,
}
})
.then((response) => {
this.list = this.list.concat(response.data.data);
this.total = response.data.total;
})
.catch()
.then(() => {
this.loading = false;
})
},
async onOpen() {
await this.$nextTick()
this.observer.observe(this.$refs.load)
},
onClose() {
this.observer.disconnect()
},
async infiniteScroll([{isIntersecting, target}]) {
if (isIntersecting) {
const ul = target.offsetParent
const scrollTop = target.offsetParent.scrollTop
this.limit = 10
this.getUsers();
await this.$nextTick()
ul.scrollTop = scrollTop
}
},
inputSearch: _.debounce( async function (search, loading) {
if (search.length) {
this.list = []
this.loading = true
this.page = 0
this.limit = 10
this.getUsers(search, loading)
await this.$nextTick()
}
}, 500),
},
}
</script>
structure
"data": [
{
"id": 1612,
"name": "Aaliyah Kassulke",
"email": "[email protected]",
"email_verified_at": null,
"created_at": "2022-05-30T08:45:08.000000Z",
"updated_at": "2022-05-30T08:45:08.000000Z"
},
CodePudding user response:
On a standard select
you can set the value
on each option
to a nested value which would be returned when selected e.g.
<select v-model="selectedUser">
<option
v-for="user in users"
:key="user.id"
:value="user.id"
>
{{ user.name }}
</option>
</select>
There should be a prop related to this for use with the v-select
in the API documentation, if not, you could just add a separate computed
value to return just the selected ID, that will update whenever a new user is selected. This is assuming that your v-select
returns the user object when selected.
computed: {
selectedStudentId() {
return this.selectedUser?.id;
}
}
CodePudding user response:
if you want only id then you can use reduce function as shown below. so you can get the direct id of the selected option in the v-model.
<v-select
:options="list"
:label="label"
:reduce="(list) => list.id"
v-model="userId"
@change="$emit('your-event',userId)"
>
now, you can listen to event @your-event in parent and get the user id.