我在 Vue 2 中构建了一个分页组件,使用无渲染模式将行为与呈现分开,并允许消费者编写自己的 UI ( https://adamwathan.me/renderless-components-in-vuejs/ )。
无渲染分页.js:
...
render() {
return this.$scopedSlots.default({
setPage: this.setPage,
totalPages: this.totalPages,
override: this.options.template // this is where the user can pass his own template
// etc
})
}
分页.jsx
import template from './template' // default template in JSX syntax
components: {RenderlessPagination},
props:['options'],
...
render(h) {
return <renderless-pagination scopedSlots={
{
default: function (props) {
return props.override ? h(
props.override,
{
attrs: {props}
}
) : template(props)(h)
}
}
}
>
</renderless-pagination>
},
这允许用户将他自己的模板传递给options.template
从而覆盖默认模板:
我的分页.vue
<template>
<div class='VuePagination' :class='props.theme.wrapper'>
<nav :class='props.theme.nav'>
<ul v-show="props.showPagination" :class="props.theme.list">
<li v-if="props.hasEdgeNav" :class='props.theme.firstPage' @click="props.setFirstPage">
<a v-bind="{...props.aProps,...props.firstPageProps}">{{props.texts.first}}</a>
</li>
<li v-if="props.hasChunksNav" :class='props.theme.prevChunk' @click="props.setPrevChunk">
<a v-bind="{...props.aProps, ...props.prevChunkProps}">{{props.texts.prevChunk}}</a>
</li>
<li :class="props.theme.prev" @click="props.setPrevPage">
<a v-bind="{...props.aProps,...props.prevProps}">{{props.texts.prevPage}}</a>
</li>
<li v-for="page in props.pages" :key="page" :class="props.pageClasses(page)"
v-on="props.pageEvents(page)">
<a v-bind="props.aProps" :class="props.theme.link">{{page}}</a>
</li>
<li :class="props.theme.next" @click="props.setNextPage">
<a v-bind="{...props.aProps, ...props.nextProps}">{{props.texts.nextPage}}</a>
</li>
<li v-if="props.hasChunksNav" :class='props.theme.nextChunk' @click="props.setNextChunk">
<a v-bind="{...props.aProps, ...props.nextChunkProps}">{{props.texts.nextChunk}}</a>
</li>
<li v-if="props.hasEdgeNav" :class="props.theme.lastPage" @click="props.setLastPage">
<a v-bind="{...props.aProps, ...props.lastPageProps}">{{props.texts.last}}</a>
</li>
</ul>
<p v-show="props.hasRecords" :class='props.theme.count'>{{props.count}}</p>
</nav>
</div>
</template>
<script>
export default {
name: 'MyPagination',
props: ['props']
}
</script>
然后将其与插件一起使用:
import Pagination from 'vue-pagination'
import MyPagination from './MyPagination'
<pagination :options={template:MyPagination}/>
此代码在 Vue 3 上中断。这一次,scopedSlots 已与插槽统一。其次,将 h (CreateElement) 变量作为全局依赖项导入。但即使考虑了这些变化,我仍然无法找到可行的解决方案。
在 Vue 3 中重写此逻辑的最佳方法是什么?