我想创建一个带有自定义数据呈现(模板)的bootstrap-vue表的父组件。
现在,这看起来像这样:
<b-table
:items="result"
:fields="fields"
:current-page="currentPage"
:per-page="perPage">
<template slot="Index" slot-scope="data">
{{ data.index + 1 }}
</template>
<!-- more templates for various columns here -->
</b-table>
<b-pagination
align="center"
:total-rows="result.length"
v-model="currentPage"
:per-page="perPage"
/>
我想把它包装在一个组件中的原因是因为我使用了这个表布局,包括分页和它的所有属性(比如带条纹的、有边框的等)。很多次。
唯一变化的是列模板。
我知道,Vue的方法是创建一个像<slot name="x"></slot>
这样的插槽,然后用<template slot="x">...</template>
填充它。一方面,这与bootstrap-vue template
一致,另一方面,bootstrap-vue似乎只有在模板被正确放置在b-table
中时才能正确呈现它们。
基本上,我想要实现的是这样一个组件:
<b-table>
<slot name="templates"/>
</b-table>
<b-pagination stuff.../>
并在子组件中使用它,如下所示:
<TemplateTable>
<template slot="templates">
<template slot="Index" slot-scope="data">
{{ data.index + 1 }}
</template>
<!-- more templates -->
</template>
</TableTemplate>
有没有人做过这样的事情,并想出了解决它的方法?
发布于 2020-08-12 11:26:02
只需构建您的自定义组件,并传递您需要的任何自定义道具,如下所示:
<template>
<b-table v-bind="$attrs" v-on="$listeners" custom-prop="any">
<slot v-for="(_, name) in $slots" :name="name" :slot="name" />
<template
v-for="(_, name) in $scopedSlots"
:slot="name"
slot-scope="slotData"
><slot :name="name" v-bind="slotData"
/></template>
</b-table>
</template>
<script>
export default {
name: 'AppTable',
}
</script>
<style scoped></style>
这就像一个护身符!
发布于 2018-09-26 19:17:33
You can use a component's render function将插槽和scopedSlots传递给另一个组件(如b-table
)。但这样就不能使用模板了。让您拥有一个模板(具有分页、搜索等功能)您可以将呈现组件包装到另一个具有模板的组件中。因此,您将拥有一个包含分页的custom-table
组件和一个table-wrapper
组件,并且table-wrapper
组件将呈现一个b-table
。
这里有一个非常具体的例子..
const constItems = [{
index: 0,
isActive: true,
age: 40,
first_name: 'Dickerson',
last_name: 'Macdonald'
},
{
index: 1,
isActive: false,
age: 21,
first_name: 'Larsen',
last_name: 'Shaw'
},
{
index: 2,
isActive: false,
age: 89,
first_name: 'Geneva',
last_name: 'Wilson'
},
{
index: 3,
isActive: true,
age: 38,
first_name: 'Jami',
last_name: 'Carney'
}
];
const bTableProps = {
items: {
type: [Array, Function],
default: undefined
},
fields: {
type: [Object, Array],
default: undefined
}
};
const constFields = [
'index',
'isActive',
'age',
'first_name',
'last_name'
];
Vue.component('table-wrapper', {
props: Object.assign({}, bTableProps),
render(h) {
return h('b-table', {
props: this.$props,
slots: this.$parent.$slots,
scopedSlots: this.$parent.$scopedSlots,
on: {
'row-clicked': (item, index, event) => alert('clicked ' + index)
}
});
}
});
Vue.component('custom-table', {
template: '<div><h3>hello table</h3><table-wrapper :items="items" :fields="fields"></table-wrapper></div>',
props: Object.assign({}, bTableProps)
});
new Vue({
el: "#app",
data: {
items: constItems,
fields: constFields
}
});
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<link href="https://unpkg.com/bootstrap@4.1.3/dist/css/bootstrap.min.css" rel="stylesheet" />
<link href="https://unpkg.com/bootstrap-vue@2.0.0-rc.11/dist/bootstrap-vue.css" rel="stylesheet" />
<script src="https://unpkg.com/babel-polyfill@6.26.0/dist/polyfill.min.js"></script>
<script src="https://unpkg.com/bootstrap-vue@2.0.0-rc.11/dist/bootstrap-vue.js"></script>
<div id="app">
<custom-table :items="items" :fields="fields">
<template slot="index" slot-scope="data">
{{ data.index + 1 }}
</template>
</custom-table>
<custom-table :items="items" :fields="fields">
<template slot="index" slot-scope="data">
{{ data.index + 2 }}
</template>
</custom-table>
<custom-table :items="items" :fields="fields">
<template slot="index" slot-scope="data">
{{ data.index + 3 }}
</template>
</custom-table>
</div>
发布于 2019-10-31 15:48:18
感谢@nardnob,这就是我在.vue
组件中使用的东西。我的app.js
文件中已经加载了所有的b-table
组件。因此缺少import语句。
首先是TableWrapper.vue
。我添加了Object.assign(this.$attrs, this.$props)
,以确保来自CustomTable
的任何未定义的props
仍然可以通过组合$attrs
和$props
传递到b-table
。
<script>
export default {
components: {},
props: [
'items',
'fields'
],
mixins: [],
data: function () {
return {
//
}
},
render(h) {
return h('b-table', {
props: Object.assign(this.$attrs, this.$props),
slots: this.$parent.$slots,
scopedSlots: this.$parent.$scopedSlots,
on: {
// 'row-clicked': (item, index, event) => alert('clicked ' + index)
}
});
},
computed: {
//
},
created() {
//
},
mounted() {
//
},
methods: {
//
},
watch: {
//
}
}
</script>
然后是CustomTable.vue
<template>
<table-wrapper
:items="items"
:fields="fields"
:striped="true"
></table-wrapper>
</template>
<script>
export default {
components: {},
props: [
'fields',
'items',
],
mixins: [],
data: function () {
return {
//
}
},
computed: {
//
},
created() {
//
},
mounted() {
//
},
methods: {
//
},
watch: {
//
}
}
</script>
最后:
<custom-table
:fields="[
{
key: 'code',
label: 'Code',
},
{
key: 'title',
label: 'Titel',
},
{
key: 'start_date',
label: 'Start',
},
{
key: 'end_date',
label: 'End',
},
{
key: 'log',
label: 'Log'
}
]"
:items="episodes"
>
<template v-slot:cell(log)="data">
<i class="fa-icon fa-search ml-1 is-hoverable" @click="test"></i>
</template>
</custom-table>
https://stackoverflow.com/questions/51040281
复制相似问题