Vue 2 добавить слот в родительский компонент - PullRequest
0 голосов
/ 06 февраля 2020

У меня проблема с Vue 2 . У меня есть главный компонент под названием search. vue <product-search></product-search>. Этот компонент имеет свойство с именем :view, это может быть таблица, маленькие столбцы, средние столбцы и многое другое. Все эти представления являются пользовательскими компонентами: table_view.vue, small_columns.vue et c. На мой взгляд, у меня есть слот под названием действия <slot name="actions"></slot>. Теперь я хочу добавить действия из основного компонента (product-search. vue) и передать их компонентам представления. Например:

Кто-нибудь знает, как мне этого добиться?

Я сократил количество кода для лучшего чтения.

blank_page. vue

    <template>
        <div>
            <search-product :multiple="false" :shop="shop" v-model="items" display="table" :modal="false">
                    <template slot="table-actions">
                        <div>Here some extra actions</div>
                    </template>
            </search-product>
        </div>
    </template>

    <script>
        export default {
            props: {
                shop: {}
            },
            data() {
                return {
                    items: []
                };
            }
        }
    </script>

поиск. vue

    <template>
        <div>
            <template>
                <component v-bind:is="getDisplay()" :multiple="multiple" :items="items" v-model="selectedItems"></component>

            </template>
        </div>
    </template>

    <script>
        import SearchButton from './search-button.vue';
        import SearchInput from './input.vue';
        import DisplayTable from './displays/table.vue';
        import DisplaySmallGrid from './displays/small-grid.vue';
        import DisplayMediumGrid from './displays/medium-grid.vue';
        import DisplayLargeGrid from './displays/large-grid.vue';

        export default {
            components: {
                searchButton: SearchButton,
                searchInput: SearchInput,
                displayTable: DisplayTable,
                displaySmallGrid: DisplaySmallGrid,
                displayMediumGrid: DisplayMediumGrid,
                displayLargeGrid: DisplayLargeGrid,
            },
            props: {
                modal: {
                    default: false
                },
                multiple: {
                    default: true
                },
                value: {},
                shop: {},
                display: {
                    default: 'table'
                }
            },
            watch: {
                selectedItems(data) {
                    this.$emit('input', data);
                }
            },
            data() {
                return {
                    q: '',
                    items: [],
                    selectedItems: [],
                    modalOpen: false,
                    templates: {
                        DisplayTable
                    }
                };
            },
            methods: {
                getDisplay() {
                    return 'display' + this.display.charAt(0).toUpperCase() + this.display.slice(1);
                },
                toggleModal() {
                    this.modalOpen = !this.modalOpen;
                }
            }
        }
    </script>

просмотр таблицы. vue

<template>
    <div :class="panel ? 'card' : ''">
        <div :class="panel ? 'card-body' : ''">
            <table class="table table-striped table-hover">
                <thead>
                <tr>
                    <th>ID</th>
                    <th>Actions</th>
                </tr>
                </thead>
                <tbody>
                <tr v-for="item in items">
                    <td v-text="item.id"></td>

                    <td>
                        <slot name="table-actions"></slot>
                    </td>
                </tr>
                </tbody>
            </table>
        </div>
    </div>
</template>

<script>
    export default {
        props: {
            items: {},
            value: {},
            multiple: {},
            panel: {
                default: true
            }
        },
    }

</script>

1 Ответ

0 голосов
/ 06 февраля 2020

У вас есть 2 решения: передать его от родителя внуку в качестве пропуска через дочерний компонент.

parent: data: yourAction => child: props: yourAction => grandchild: props: yourAction

, а затем используйте v- html для его рендеринга в случае, если у него есть html отметьте

или передайте его в качестве реквизита ребенку и используйте слот для передачи его внуку.

Первое решение

blank_page. vue

    <template>
        <div>
            <search-product :multiple="false" :shop="shop" v-model="items" display="table" :modal="false" :yourAction:"yourAction">

            </search-product>
        </div>
    </template>

    <script>
        export default {
            props: {
                shop: {}
            },
            data() {
                return {
                    items: [],
                    yourAction: "Here some stuff"
                };
            }
        }
    </script>

search. vue

    <template>
        <div>
            <template>
                <component v-bind:is="getDisplay()" :multiple="multiple" :items="items" v-model="selectedItems" :yourAction="yourAction"></component>

            </template>
        </div>
    </template>

    <script>
        import SearchButton from './search-button.vue';
        import SearchInput from './input.vue';
        import DisplayTable from './displays/table.vue';
        import DisplaySmallGrid from './displays/small-grid.vue';
        import DisplayMediumGrid from './displays/medium-grid.vue';
        import DisplayLargeGrid from './displays/large-grid.vue';

        export default {
            components: {
                searchButton: SearchButton,
                searchInput: SearchInput,
                displayTable: DisplayTable,
                displaySmallGrid: DisplaySmallGrid,
                displayMediumGrid: DisplayMediumGrid,
                displayLargeGrid: DisplayLargeGrid,
            },
            props: {
                yourAction:{
                default:""
                },
                modal: {
                    default: false
                },
                multiple: {
                    default: true
                },
                value: {},
                shop: {},
                display: {
                    default: 'table'
                }
            },
            watch: {
                selectedItems(data) {
                    this.$emit('input', data);
                }
            },
            data() {
                return {
                    q: '',
                    items: [],
                    selectedItems: [],
                    modalOpen: false,
                    templates: {
                        DisplayTable
                    }
                };
            },
            methods: {
                getDisplay() {
                    return 'display' + this.display.charAt(0).toUpperCase() + this.display.slice(1);
                },
                toggleModal() {
                    this.modalOpen = !this.modalOpen;
                }
            }
        }
    </script>

table_view. vue

<template>
    <div :class="panel ? 'card' : ''">
        <div :class="panel ? 'card-body' : ''">
            <table class="table table-striped table-hover">
                <thead>
                <tr>
                    <th>ID</th>
                    <th>Actions</th>
                </tr>
                </thead>
                <tbody>
                <tr v-for="item in items">
                    <td v-text="item.id"></td>

                    <td v-html="yourAction">
                    </td>
                </tr>
                </tbody>
            </table>
        </div>
    </div>
</template>

<script>
    export default {
        props: {
            yourAction,
            items: {},
            value: {},
            multiple: {},
            panel: {
                default: true
            }
        },
    }

</script>

Второе решение

blank_page. vue: так же, как в первом примере, который я вам дал, вы передаете свое действие как реквизит

search. vue: вы передаете Пропускает в слот, как вы это делали в примере blank_page. vue

table_view. vue: остаются прежними

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...