【问题标题】:Vue 2 add slot to parent componentVue 2 向父组件添加插槽
【发布时间】:2020-02-06 13:47:17
【问题描述】:

我遇到了 Vue 2 的问题。我有一个名为 search.vue <product-search></product-search> 的主要组件。这个组件有一个叫做:view的属性,这个视图可以是表格、小列、中列等等。所有这些视图都是自定义组件:table_view.vuesmall_columns.vue 等。在我看来,我有一个名为操作<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>

search.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>

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>
                        <slot name="table-actions"></slot>
                    </td>
                </tr>
                </tbody>
            </table>
        </div>
    </div>
</template>

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

</script>

【问题讨论】:

    标签: javascript vue.js vuejs2


    【解决方案1】:

    您有 2 个解决方案:通过子组件将其作为道具从父级传递给孙子级。

    父:数据:你的动作 => 孩子:道具:你的动作 => 孙:道具:你的动作

    然后使用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:你将 props 传递给 slot,就像你在 blank_page.vue 的例子中所做的那样

    table_view.vue : 保持不变

    【讨论】:

    • 如果您需要使用插槽中的项目,此解决方案不起作用
    • 据我了解,您正试图将一些 Html 或文本插入到孙组件中。你想在那里插入什么样的项目?
    猜你喜欢
    • 2021-02-06
    • 2020-02-23
    • 2021-01-15
    • 2018-04-18
    • 2020-12-24
    • 2018-11-18
    • 1970-01-01
    • 2021-02-01
    • 2018-09-14
    相关资源
    最近更新 更多