Vue antdev - pass arguments to title scopedSlots

56 views Asked by At

I use AntDesign Vue version 1.7.8 (here).
I need to generate custom columns titles according to data I obtain via API.

This is how I figured out to generate titles with scope, the problem is that I need to pass some data to the title scope, and cannot figure out how to do it:

var Main = {
    data() {
      return {
        columns: [
          {
            title: 'Category',
            dataIndex: 'category',
          },
        ],
        myData: [
          {id: 1, category: 'a1', ch05: 34, ch07: 36, ch08: 37},
          {id: 2, category: 'a2', ch05: 54, ch07: 51, ch08: 32},
          {id: 3, category: 'a3', ch05: 88, ch07: 89, ch08: 91},
        ],
      }
    },
    mounted() {
      // Dynamically created by API access
      let channels = [
        {code: '05', name: 'General'},
        {code: '07', name: 'Clients'},
        {code: '08', name: 'Providers'}
      ];
      
      channels.forEach(channel => {
        let column = {
          //title: 'Channel ' + channel.code,
          dataIndex: 'ch' + channel.code,
          scopedSlots: { title: 'channelTitle'},
        };
        this.columns.push(column);
      });
    },
  }
var Ctor = Vue.extend(Main)
new Ctor().$mount('#app')
.alertdiv {
  display: block;
  border:1px solid red;
  background-color: #f7e0e0;
  padding:3px 10px;
  margin: 0px 3px 30px 3px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.9/vue.js"></script>
<script src="https://unpkg.com/[email protected]/dist/vue.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/ant-design-vue/1.7.8/antd.min.js" integrity="sha512-o1PLXMVDD8r7lQlPXWHTyJxH7WpFm75dsSfzsa04HRgbeEHJv/EbaxEgACaB6mxbBmHU+Dl64MflqQB7cKAYpA==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>

<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/ant-design-vue/1.7.8/antd.css" integrity="sha512-Zl/2o30l4LayZodj2IuRoBhZLgQNvKnnSTwB08236BoPAhbhhS8dZltQfyftSVdEVrJ43uSyh/Keh1t/5yP5Ug==" crossorigin="anonymous" referrerpolicy="no-referrer" />

<div id="app">
  <template>
    <div class="alertdiv">Instead of <b>Channel xx</b>, each column should have its own custom title</div>
    <a-table
      :columns="columns"
      :row-key="record => record.id"
      :data-source="myData"
    >
      <span slot="channelTitle">
        Channel xx
      </span>
    </a-table>
  </template>
</div>

===== EDIT ======

I need to pass data to the title slot, since I want to apply some elements which are not simple text, based on the column data.

1

There are 1 answers

4
Keyboard Corporation On

You can use slots:{ title:'customTitle'} for title in ant.

In you code, I remove the mounted and use the package of ant to create a custom header.

Edit

*For this dynamic header, I do making title in methods and just push it to columns variable. Then call it as usual without using slots.

var Main = {
data() {
    return {
    columns: [
        {
        title: 'Category',
        dataIndex: 'category',
        },
    ],
    myData: [
        {id: 1, category: 'a1', ch05: 34, ch07: 36, ch08: 37},
        {id: 2, category: 'a2', ch05: 54, ch07: 51, ch08: 32},
        {id: 3, category: 'a3', ch05: 88, ch07: 89, ch08: 91},
    ],
    }
},
created(){
    this.tableHeader()
},
methods:{
    tableHeader(){
        let channels = [
            {code: '05', name: 'General'},
            {code: '07', name: 'Clients'},
            {code: '08', name: 'Providers'}
        ];
        channels.forEach(channel => {
            let column = {
            dataIndex: 'ch' + channel.code,
            title: 'Channel ' + channel.code,
            };
            this.columns.push(column);
        });
    }
},
}
var Ctor = Vue.extend(Main)
new Ctor().$mount('#app')
.alertdiv {
  display: block;
  border:1px solid red;
  background-color: #f7e0e0;
  padding:3px 10px;
  margin: 0px 3px 30px 3px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.9/vue.js"></script>
<script src="https://unpkg.com/[email protected]/dist/vue.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/ant-design-vue/1.7.8/antd.min.js" integrity="sha512-o1PLXMVDD8r7lQlPXWHTyJxH7WpFm75dsSfzsa04HRgbeEHJv/EbaxEgACaB6mxbBmHU+Dl64MflqQB7cKAYpA==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/ant-design-vue/1.7.8/antd.css" integrity="sha512-Zl/2o30l4LayZodj2IuRoBhZLgQNvKnnSTwB08236BoPAhbhhS8dZltQfyftSVdEVrJ43uSyh/Keh1t/5yP5Ug==" crossorigin="anonymous" referrerpolicy="no-referrer" />

<div id="app">
    <template>
        <div class="alertdiv">Instead of <b>Channel xx</b>, each column should have its own custom title</div>
        <a-table
            :columns="columns"
            :data-source="myData"
        >
        </a-table>
    </template>
</div>

Other way

Another way to achieve a dynamic header is to use <a-table-column-group>

var Main = {
data() {
    return {
    columns: [
        {
        key:"category",
        title: 'Category',
        dataIndex: 'category',
        },
    ],
    myData: [
        {id: 1, category: 'a1', ch05: 34, ch07: 36, ch08: 37},
        {id: 2, category: 'a2', ch05: 54, ch07: 51, ch08: 32},
        {id: 3, category: 'a3', ch05: 88, ch07: 89, ch08: 91},
    ],
    }
},
created(){
    this.tableHeader()
},
methods:{
    tableHeader(){
        let channels = [
            {code: '05', name: 'General'},
            {code: '07', name: 'Clients'},
            {code: '08', name: 'Providers'}
        ];
        channels.forEach(channel => {
            let column = {
            //title: 'Channel ' + channel.code,
            key: channel.code,
            title: 'ChannelTitle' + channel.code,
            dataIndex: 'ch' + channel.code,
            };
            this.columns.push(column);
            console.log(this.columns)
        });
    }
},
}
var Ctor = Vue.extend(Main)
new Ctor().$mount('#app')
.alertdiv {
  display: block;
  border:1px solid red;
  background-color: #f7e0e0;
  padding:3px 10px;
  margin: 0px 3px 30px 3px;
}
    <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.9/vue.js"></script>
    <script src="https://unpkg.com/[email protected]/dist/vue.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/ant-design-vue/1.7.8/antd.min.js" integrity="sha512-o1PLXMVDD8r7lQlPXWHTyJxH7WpFm75dsSfzsa04HRgbeEHJv/EbaxEgACaB6mxbBmHU+Dl64MflqQB7cKAYpA==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/ant-design-vue/1.7.8/antd.css" integrity="sha512-Zl/2o30l4LayZodj2IuRoBhZLgQNvKnnSTwB08236BoPAhbhhS8dZltQfyftSVdEVrJ43uSyh/Keh1t/5yP5Ug==" crossorigin="anonymous" referrerpolicy="no-referrer" />

<div id="app">
    <template>
        <div class="alertdiv">Instead of <b>Channel xx</b>, each column should have its own custom title</div>
        <a-table :data-source="myData">
            <a-table-column-group v-for="header in columns">
                <a-table-column :key="header.key == 'category' ? 'category' : 'ch'+[header.key]" :data-index="header.key == 'category' ? 'category' : 'ch'+[header.key]">
                    <span slot="title" style="color: #1890ff">{{ header.title }}</span>
                </a-table-column>
            </a-table-column-group>
        </a-table>
    </template>
</div>

ADDITIONAL

You can use slots by doing this way.

var Main = {
data() {
    return {
    columns: [
        {
        key:"category",
        title: 'Category',
        dataIndex: 'category',
        },
    ],
    myData: [
        {id: 1, category: 'a1', ch05: 34, ch07: 36, ch08: 37},
        {id: 2, category: 'a2', ch05: 54, ch07: 51, ch08: 32},
        {id: 3, category: 'a3', ch05: 88, ch07: 89, ch08: 91},
    ],
    }
},
created(){
    this.tableHeader()
},
methods:{
    tableHeader(){
        let channels = [
            {code: '05', name: 'General'},
            {code: '07', name: 'Clients'},
            {code: '08', name: 'Providers'}
        ];
        channels.forEach(channel => {
            let column = {
            //title: 'Channel ' + channel.code,
            dataIndex: 'ch' + channel.code,
            key: channel.code,
            slots: { title: 'channelTitle' + channel.code },
            };
            this.columns.push(column);
        });
    }
},
}
var Ctor = Vue.extend(Main)
new Ctor().$mount('#app')
.alertdiv {
    display: block;
    border:1px solid red;
    background-color: #f7e0e0;
    padding:3px 10px;
    margin: 0px 3px 30px 3px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.9/vue.js"></script>
<script src="https://unpkg.com/[email protected]/dist/vue.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/ant-design-vue/1.7.8/antd.min.js" integrity="sha512-o1PLXMVDD8r7lQlPXWHTyJxH7WpFm75dsSfzsa04HRgbeEHJv/EbaxEgACaB6mxbBmHU+Dl64MflqQB7cKAYpA==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/ant-design-vue/1.7.8/antd.css" integrity="sha512-Zl/2o30l4LayZodj2IuRoBhZLgQNvKnnSTwB08236BoPAhbhhS8dZltQfyftSVdEVrJ43uSyh/Keh1t/5yP5Ug==" crossorigin="anonymous" referrerpolicy="no-referrer" />

<div id="app">
    <template>
        <a-table :data-source="myData" :columns="columns">
            <template v-for="data in columns">
                <span :slot="'channelTitle' + data.key">
                    <span :style="data.key == 05 && 'color:blue' || data.key == 07 && 'color:red' || data.key == 08 && 'color:green'">
                        Custom Header {{ data.key }}
                    </span>
                </span>
            </template>
        </a-table>
    </template>
</div>