Tengo una lista desplazable de la que puedo seleccionar varios elementos. Quiero implementar mediante programación una forma de desplazarme hasta la parte superior de la lista cada vez que cambio la entrada de búsqueda.
Comportamiento deseado: Por ejemplo; cuando escribo 'b' en la lista de búsqueda y me desplazo hacia abajo, si vuelvo a escribir 'e' me gustaría que se desplace hasta la parte superior
Aquí hay un ejemplo de código que muestra lo que me gustaría hacer, probé dos métodos diferentes. Probé dos enfoques diferentes en el código a continuación, donde utilizo la función scrollTop del elemento html y la función goTo de vuetify, pero ninguno de ellos funcionó.
Demostración de código-> https://www.codeply.com/p/ZGBNEHW7YS
En caso de que la demostración caduque, el código real;
<div id="app"> <v-app> <v-main class="py-3 px-5"> <h1 class="teal--text">AutoComplete Infinite Scroll Example</h1> <v-autocomplete id="autoComplete" ref="autoComplete" v-model="selected" :items="beers" item-text="name" item-value="id" :search-input.sync="search" label="Search the beers.." return-object multiple autocomplete="off" > <template v-slot:append-item> <div v-intersect="onIntersect" class="pa-4 teal--text"> Loading more items ... </div> </template> </v-autocomplete> </v-main> </v-app> new Vue({ el: '#app', vuetify: new Vuetify(), data() { return { search:'', beers: [], selected: null, perPage: 30, page: 1, } }, methods: { getBeers() { console.log('page', this.page) const apiUrl = `https://api.punkapi.com/v2/beers?page=${this.page}&per_page=${this.perPage}` axios.get(apiUrl) .then(response => { this.beers = [ ...this.beers, ...response.data ] }) }, onIntersect () { console.log('load more...') this.page += 1 this.getBeers() }, }, watch:{ search:function(){ //first method let myId=document.getElementById('autoComplete') if(myId){ myId.scrollTop = 0 } //second method with ref and vuetify goto this.$nextTick(() => { this.$vuetify.goTo(this.$refs.autoComplete) }) } }, created() { this.getBeers() } })Así es como lo resolví usando el ejemplo de zergski.
Se requirió el casting debido al texto mecanografiado.
scrollTop(): void { let scrollList = document.querySelector('.v-autocomplete__content') let firstElement = document.querySelector('.company-item-name') as HTMLElement if (scrollList && firstElement && firstElement.offsetTop) { scrollList.scrollTop = firstElement.offsetTop } },Necesitas algo como esto (ver demostración en página completa)
new Vue({ el: '#app', vuetify: new Vuetify(), data: () => ({ beers: [], selected: null, perPage: 30, page: 1, }), created() { this.getBeers() }, methods: { goToTop(){ this.beers = []; this.page = 1; this.getBeers(); }, getBeers() { console.log('page', this.page) const apiUrl = `https://api.punkapi.com/v2/beers?page=${this.page}&per_page=${this.perPage}` axios.get(apiUrl) .then(response => { this.beers = [ ...this.beers, ...response.data ] }) }, onIntersect () { this.page += 1 this.getBeers() }, }, }) .scroll-to-top { position:sticky; bottom:8px; width:100%; display:flex; justify-content :right; background-color: rgba(0, 0, 0, 0); } <script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.24.0/axios.min.js"></script> <link href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900" rel="stylesheet"> <link href="https://cdn.jsdelivr.net/npm/@mdi/font@4.x/css/materialdesignicons.min.css" rel="stylesheet"> <link href="https://cdn.jsdelivr.net/npm/vuetify@2.x/dist/vuetify.min.css" rel="stylesheet"> <script src="https://cdn.jsdelivr.net/npm/vue@2.x/dist/vue.js"></script> <script src="https://cdn.jsdelivr.net/npm/vuetify@2.x/dist/vuetify.js"></script> <div id="app"> <v-app id="inspire"> <v-card> <v-container fluid> <v-row align="center" > <v-col cols="12"> <v-autocomplete v-model="selected" :items="beers" item-text="name" item-value="id" label="Search da beers.." return-object autocomplete="off" > <template v-slot:append-item> <div v-intersect="onIntersect" class="pa-4 teal--text"> Loading more items ... </div> <div class="text-right pr-4 scroll-to-top"> <v-btn color="primary" small class="align-right" @click="goToTop" > Go to top </v-btn> </div> </template> </v-autocomplete> </v-col> </v-row> </v-container> </v-card> </v-app> </div>