Компоненты без рендеринга в Vue 3

Я создал компонент разбивки на страницы в Vue 2, используя шаблон без рендеринга, чтобы отделить поведение от представления и позволить потребителю составлять свой собственный пользовательский интерфейс (https://adamwathan.me/renderless-components-in-vuejs/).

RenderlessPagination.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
  })
}

Pagination.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 таким образом переопределив шаблон по умолчанию:

MyPagination.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?

0 ответов

Другие вопросы по тегам