[Timeline] Limitations of using Vue component as items or groups
I'm just starting to use your (awesome :wave: ) project. I'd like to show some complex items (with images) in timeline, and since I already have some Vue components to handle this, I used your example to try it.
However, I noticed some limitations:
- Reactivity is non-existent. Moreover, the template function is called on every select and unselect event, and it build a new component every time. I kind of solved it by caching instances of component items, but it doesn't solve the fact that changes in component state are not reflected
- Only HTML and CSS from the initial state. The rest is ignored, and it includes events. For example, I used some router links, and they are not handled by JS event, but trigger a page reload, which is… undesired :wink:
I don't know if those limitations can be lifted. The template method from visjs-timeline seems out of control. Maybe there is something to do to hook on Vue component and call redraw when needed?
And for JS and events, I don't even think this is possible, so maybe it could be good to write it somewhere in the documentation.
I'm glad you like it @Glandos. I too use some complex vue components in the items and I also use a JS Map to cache the components to avoid to recreate them.
For the lack of reactivity within the component, I either use this.$parent either vuex. It is a bit clunky but I haven't found a better solution yet.
I'm not sure I fully understand/encountered your second point, if you ever have the time to show me an example.
Right, you remind me that I found another solution, that works really better for me. Here is a quick excerpt. First the template:
<Timeline
ref="timeline"
:items="timelineItems"
:options="timelineOptions"
/>
<div v-show="false">
<TimelineCard
v-for="(item, index) in items"
ref="itemCards"
:key="index"
/>
</div>
Timeline is your component, and TimelineCard is a custom component I made.
Then, the data:
timelineItems = [] // Put your stuff here
timelineOptions = {
template: (item) => {
// If using typescript, see https://github.com/visjs/vis-timeline/pull/836
return this.$refs.itemCards[item.id].$el
}
}
And… this is basically it. As you can see, the trick is using refs embedded in an v-show="false" div. And now, your element belong to the Vue tree, are debuggable, reactive, hot-reloaded, etc.