vue3 封装带有分页的下拉选
时间: 2023-06-29 14:10:10 浏览: 156
可以封装一个带有分页的下拉选组件,可以使用 Vue3 的 Composition API 来实现。具体步骤如下:
1. 创建一个可复用的下拉选组件
```vue
<template>
<div class="dropdown">
<select v-model="selected" @change="handleChange">
<option v-for="item in options" :value="item.value" :key="item.value">{{ item.label }}</option>
</select>
<button v-if="showMoreButton" @click="handleLoadMore">更多</button>
</div>
</template>
<script>
import { ref, onMounted } from 'vue'
export default {
props: {
options: {
type: Array,
required: true
},
loadMore: {
type: Function,
default: null
},
pageSize: {
type: Number,
default: 10
}
},
setup(props) {
const selected = ref(props.options[0].value)
const page = ref(1)
const showMoreButton = computed(() => {
return props.loadMore && props.options.length >= page.value * props.pageSize
})
function handleChange(event) {
selected.value = event.target.value
}
function handleLoadMore() {
page.value++
props.loadMore(page.value)
}
onMounted(() => {
selected.value = props.options[0].value
})
return {
selected,
showMoreButton,
handleChange,
handleLoadMore
}
}
}
</script>
```
2. 在上述组件的基础上,添加分页功能
```vue
<template>
<div class="dropdown">
<select v-model="selected" @change="handleChange">
<option v-for="item in visibleOptions" :value="item.value" :key="item.value">{{ item.label }}</option>
</select>
<button v-if="showMoreButton" @click="handleLoadMore">更多</button>
</div>
</template>
<script>
import { ref, onMounted, computed } from 'vue'
export default {
props: {
options: {
type: Array,
required: true
},
loadMore: {
type: Function,
default: null
},
pageSize: {
type: Number,
default: 10
}
},
setup(props) {
const selected = ref(props.options[0].value)
const page = ref(1)
const visibleOptions = computed(() => {
return props.options.slice(0, page.value * props.pageSize)
})
const showMoreButton = computed(() => {
return props.loadMore && props.options.length >= page.value * props.pageSize
})
function handleChange(event) {
selected.value = event.target.value
}
function handleLoadMore() {
page.value++
props.loadMore(page.value)
}
onMounted(() => {
selected.value = props.options[0].value
})
return {
selected,
visibleOptions,
showMoreButton,
handleChange,
handleLoadMore
}
}
}
</script>
```
上述代码中,我们使用 computed 属性计算出当前页的可见选项,然后在模板中渲染这些选项。同时,根据页面的大小和选项总数计算出是否需要显示更多按钮。
3. 使用包装组件
```vue
<template>
<div>
<Pagination :current="currentPage" :total="total" :pageSize="pageSize" @change="handlePageChange" />
<Dropdown
:options="options"
:loadMore="loadMore"
:pageSize="pageSize"
v-model="selectedValue"
/>
</div>
</template>
<script>
import { ref, reactive } from 'vue'
import Dropdown from './Dropdown.vue'
import Pagination from './Pagination.vue'
export default {
components: {
Dropdown,
Pagination
},
setup() {
const pageSize = 10
const currentPage = ref(1)
const total = ref(0)
const selectedValue = ref(null)
function loadMore(page) {
// 根据当前页码和每页大小计算出起始位置和结束位置
const start = (page - 1) * pageSize
const end = start + pageSize
// 模拟异步加载数据
setTimeout(() => {
// 更新选项列表和总数
options.value = [...options.value, ...mockData.slice(start, end)]
total.value = mockData.length
}, 1000)
}
function handlePageChange(page) {
currentPage.value = page
loadMore(page)
}
const options = reactive(mockData.slice(0, pageSize))
return {
pageSize,
currentPage,
total,
selectedValue,
loadMore,
handlePageChange,
options
}
}
}
const mockData = [
{ label: '选项1', value: '1' },
{ label: '选项2', value: '2' },
{ label: '选项3', value: '3' },
{ label: '选项4', value: '4' },
{ label: '选项5', value: '5' },
{ label: '选项6', value: '6' },
{ label: '选项7', value: '7' },
{ label: '选项8', value: '8' },
{ label: '选项9', value: '9' },
{ label: '选项10', value: '10' },
{ label: '选项11', value: '11' },
{ label: '选项12', value: '12' },
{ label: '选项13', value: '13' },
{ label: '选项14', value: '14' },
{ label: '选项15', value: '15' },
{ label: '选项16', value: '16' },
{ label: '选项17', value: '17' },
{ label: '选项18', value: '18' },
{ label: '选项19', value: '19' },
{ label: '选项20', value: '20' },
{ label: '选项21', value: '21' },
{ label: '选项22', value: '22' },
{ label: '选项23', value: '23' },
{ label: '选项24', value: '24' },
{ label: '选项25', value: '25' },
{ label: '选项26', value: '26' },
{ label: '选项27', value: '27' },
{ label: '选项28', value: '28' },
{ label: '选项29', value: '29' },
{ label: '选项30', value: '30' }
]
```
上述代码中,我们使用 Pagination 和 Dropdown 组件来分别实现分页和下拉选功能,并将它们组合在一起使用。在模板中,我们将 Pagination 放在 Dropdown 前面,这样就可以通过分页来实现动态加载选项的功能了。
阅读全文