vue Fullcalendar eventRender, add vue component

Asked By: Anonymous

I use fullcalendar.io vue extension.

And I want to hook into event render to add actions, but the event callback contains only JS element.

There is a way to inject vue component into it?

<FullCalendar
    ref="fullCalendar"
    defaultView="dayGridMonth"
    :firstDay="1"
    :editable="true"
    :draggable="true"
    :timeZone="'UTC'"
    :header="false"
    :events="events"
    :plugins="plugins"
    @eventRender="eventRender"
/>

JS

import FullCalendar from '@fullcalendar/vue'
import dayGridPlugin from '@fullcalendar/daygrid'
import interactionPlugin from '@fullcalendar/interaction';

export default {
        components: {
            FullCalendar
        },
        data () {
            return {
                loader: false,
                calendar: null,
                plugins: [
                    dayGridPlugin, interactionPlugin
                ],
                events: [
                    {"id":1,"start":"2019-11-25","end":"2019-11-27"},
                    {"id":2,"start":"2019-11-23","end":"2019-11-26"},
                    {"id":3,"start":"2019-11-22","end":"2019-11-25"},
                    {"id":4,"start":"2019-11-21","end":"2019-11-24"}
                ]
            }
        },

        mounted() {

            this.calendar = this.$refs.fullCalendar.getApi();

        },

        methods:{

            eventRender(info){

                console.log(info);

            },
        }
}

For example inside eventRender (this is dirty example of what needed):

eventRender(info){

    $(info.el).append('<component-name></component-name>');

}

Update
Another solution is Vue.extend (Don’t know if is a correct way, Any suggestions?):

add a external component:

<template>
    <v-btn @click="click" :class="type">
        <slot name="text"/>
    </v-btn>
</template>

<script>
export default {
    name: 'Button',
    props: [
        'type'
    ],
    methods: {
        click() {
            this.$emit('click')
        }
    }
}

</script>

Import into needed component

import Vue from "vue"
import Button from "./helpers/Button"
var ActionClass = Vue.extend(Button)

In render function use props and slot to eventRender

eventRender(info){

    let action = new ActionClass({
        propsData: {
             type: 'primary'
        }
    })
    action.$slots.text = 'Click me!'
    action.$mount()
    action.$on('click', () => {
         console.log(info);
    });

    info.el.appendChild(action.$el)

}

Solution

Answered By: Anonymous

UPDATE
With fullCalendar V5, there is a slot support, so this hack is not needed anymore.

So what I did in the end is used the Vue.extend() solution (including creating and destroying the component manually) Until they will add slots

Full Example (Calendar Component):

<template>
    <FullCalendar
        ref="fullCalendar"
        defaultView="dayGridMonth"
        :events="events"
        :plugins="plugins"
        @eventRender="eventRender"
        @eventDestroy="eventDestroy"
    />
</template>
<script>
    import Vue from "vue"
    import dayGridPlugin from '@fullcalendar/daygrid'
    import FullCalendar from '@fullcalendar/vue'

    //Import Event component
    import Event from "./helpers/Event"

    //Init Event component
    const EventClass = Vue.extend(Event)

    export default {
        components: {
            FullCalendar
        },
        data () {
            return {
                plugins: [
                    dayGridPlugin
                ],
                events: {
                    url: "/api/calendar",
                },
                eventsObj: {}
            }
        },

        methods:{

            //FullCalendar Render event
            eventRender(info){

                //create our component instance
                const event = new EventClass({
                    propsData: {
                        event: info.event
                    }
                })

                event.$on('edit', this.edit)

                event.$on('delete', this.delete)

                event.$mount();

                //assign created component to our eventObj with uuid as key (to destroy in future)
                this.eventsObj[event._uid] = event;

                //set data-vue="{id}"
                //append our compiled component to .fc-event
                info.el.setAttribute('data-vue-id', event._uid);
                info.el.appendChild(event.$el)

            },


            //we need to destroy out component when element is removed from calendar
            eventDestroy(info){

                //get uuid
                let id = parseInt(info.el.getAttribute('data-vue-id'));

                if(this.eventsObj[id]){

                    //if exist destroy
                    this.eventsObj[id].$destroy(true);

                }
            },

            edit(event){

                console.log("edit Click")

            },

            delete(event){

                console.log("delete Click")

            }
        }
    }
</script>

Event Component:

<template>
    <v-toolbar flat dense height="30px" class="elvation-0">
        <v-btn @click="clickHandler('edit')" color="white">
            <v-icon small>edit</v-icon>
        </v-btn>
        <v-btn @click="clickHandler('delete')" color="white">
            <v-icon small>delete</v-icon>
        </v-btn>
    </v-toolbar>
</template>
<script>
export default {
    name: 'Event',
    props: ['event']
    methods: {
        clickHandler(type) {
            this.$emit(type, this.event)
        }
    }
}
</script>

Windows 10 Kaufen Windows 10 Pro Office 2019 Kaufen Office 365 Lizenz Windows 10 Home Lizenz Office 2019 Home Business Kaufen windows office 365 satın al follower kaufen instagram follower kaufen porno