如何将其转换为使用Vue 3中的组合api脚本设置



我在我的项目中使用组合api和脚本设置,我需要vue-select npm包的这一部分。但我不完全确定如何转换它。

<template>
<v-select
:options="paginated"
:filterable="false"
@open="onOpen"
@close="onClose"
@search="(query) => (search = query)"
>
<template #list-footer>
<li v-show="hasNextPage" ref="load" class="loader">
Loading more options...
</li>
</template>
</v-select>
</template>
<script>
import countries from '../data/countries'
export default {
name: 'InfiniteScroll',
data: () => ({
observer: null,
limit: 10,
search: '',
}),
computed: {
filtered() {
return countries.filter((country) => country.includes(this.search))
},
paginated() {
return this.filtered.slice(0, this.limit)
},
hasNextPage() {
return this.paginated.length < this.filtered.length
},
},
mounted() {
/**
* You could do this directly in data(), but since these docs
* are server side rendered, IntersectionObserver doesn't exist
* in that environment, so we need to do it in mounted() instead.
*/
this.observer = new IntersectionObserver(this.infiniteScroll)
},
methods: {
async onOpen() {
if (this.hasNextPage) {
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
await this.$nextTick()
ul.scrollTop = scrollTop
}
},
},
}
</script>
<style scoped>
.loader {
text-align: center;
color: #bbbbbb;
}
</style>

在不知道您尝试了什么以及有哪些外部变量/脚本可用的情况下,编写代码并不容易。也许这给你一个想法,这可能是如何在设置脚本:

<template>
<v-select
:options="paginated"
:filterable="false"
@open="onOpen"
@close="onClose"
@search="(query) => (search = query)"
>
<template #list-footer>
<li v-show="hasNextPage" ref="load" class="loader">Loading more 
options...</li>
</template>
</v-select>
</template>
<script setup>
import countries from "../data/countries";
import { onMounted, computed, ref } from "vue";
const observer = ref(null);
const limit = ref(10);
const search = "";
const filtered = computed(() => {
return countries.filter((country) => country.includes(this.search));
});
const paginated = computed(() => {
return filtered.value.slice(0, this.limit);
});
const hasNextPage = computed(() => {
return paginated.value.length < this.filtered.length;
});
onMounted(() => {
observer.value = new IntersectionObserver(infiniteScroll);
});
async function onOpen() {
if (hasNextPage) {
await $nextTick();
observer.value.observe($refs.load);
}
}
function onClose() {
observer.value.disconnect();
}
async function infiniteScroll([{ isIntersecting, target }]) {
if (isIntersecting) {
const ul = target.offsetParent;
const scrollTop = target.offsetParent.scrollTop;
limit.value += 10;
await $nextTick();
ul.scrollTop = scrollTop;
}
}
</script>
<style scoped>
.loader {
text-align: center;
color: #bbbbbb;
}
</style>

最新更新