编程语言
首页 > 编程语言> > javascript-Vue组件作为另一个组件的子组件

javascript-Vue组件作为另一个组件的子组件

作者:互联网

我正在努力将现有主题转换为可重用的组件.

我目前有一个像这样的按钮组件:

<template>
    <a :href="link" class="button" :class="styling"><slot></slot></a>
</template>

<script>
export default {
    props: {
        link: {},
        styling: {
            default: ''
        }
    }
}
</script>

而且,在我的HTML中,我像这样使用它:

<vue-button link="#" styling="tiny bg-aqua">Button 1</vue-button>

现在,我尝试使用现有的按钮组件创建一个“按钮组”.

我想做的是这样的:

<vue-button-group styling="radius tiny">
    <vue-button link="#" styling="tiny bg-aqua">Button 1</vue-button>
    <vue-button link="#" styling="tiny bg-aqua">Button 2</vue-button>
    <vue-button link="#" styling="tiny bg-aqua">Button 3</vue-button>
    <vue-button link="#" styling="tiny bg-aqua">Button 4</vue-button>
</vue-button-group>

我是VueJS的新手,对处理此类问题的正确方法有些困惑.我希望能够根据需要将尽可能多的按钮组件传递到组中.

到目前为止,这是按钮组的内容:

<template>
    <ul class="button-group" :class="styling">
        <li><slot></slot></li>
    </ul>
</template>

<script>
    export default {
        props: {
            styling: {
                default: ''
            }
        }
    }
</script>

当然,这可以通过传递单个按钮来实现,但是我似乎无法弄清楚如何在将每个按钮包含在其自己的列表项中的同时提供更多的功能.

我对此的任何建议或更正将不胜感激.谢谢.

解决方法:

由于您想对组件的输出进行高级处理,因此可能是时候选择render functions了,因为它们可以提供更大的灵活性:

Vue.component('button-group', {
    props: {
        styling: {
            default: ''
        }
    },
    render(createElement) { // createElement is usually called `h`
        // You can also do this in 1 line, but that is more complex to explain...
        // const children = this.$slots.default.filter(slot => slot.tag).map(slot => createElement('li', {}, [slot]))
        const children = [];
        for(let i = 0; i < this.$slots.default.length; i++) {
            if(!this.$slots.default[i].tag) {
                // Filter out "text" nodes, so we don't make li elements
                // for the enters between the buttons
                continue;
            }
            children.push(createElement('li', {}, [
                this.$slots.default[i]
            ]));
        }

        return createElement('ul', {staticClass: "button-group",class: this.styling}, children);
    }
})

var app = new Vue({
  el: '#app',
})
.rainbow-background {
    /* todo: implement rainbow background */
    border: red 1px solid;
}
.button-group {
    border-color: blue;
}
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.17/dist/vue.js"></script>

<div id="app">
    <button-group styling="rainbow-background">
        <button>hi</button>
        <button>How are you?</button>
        <button>I'm fine</button>
        <button>Have a nice day!</button>
    </button-group>
</div>

渲染函数通过返回虚拟html结构来工作,该结构是通过重复调用createElement函数而生成的. createElement接受3个参数,标记名(如ul或li),选项对象和子代列表.

首先,我们生成一个包含传入插槽的子代列表,这些子代存储在this.$slots.default中.

然后,我们遍历此列表,过滤掉基本上是文本的传入插槽数据,这是因为HTML将标记之间的空白视为文本的方式.

现在我们几乎完成了最后的结构,现在将slot元素包装在一个新生成的li标记中,然后完成将所有内容包装在具有适当类名的新ul标记中的生成.

标签:vue-js,vuejs2,html,javascript
来源: https://codeday.me/bug/20191108/2009149.html