olifolkerd / tabulator

Interactive Tables and Data Grids for JavaScript
http://tabulator.info
MIT License
6.62k stars 813 forks source link

Vue 3: using vue components in formatter function #4375

Open LeXaMeN opened 8 months ago

LeXaMeN commented 8 months ago

Vue 3

I need to use router-link in formatter.

Right now I am using the following function:

interface FormatterComponentOptions {
  // parent?: any,
  props: Record<string, any>,
  template: string
}
export function formatterComponent<T>(cell: CellComponent, options: FormatterComponentOptions) {
  const component = defineComponent({
    // parent: options.parent,
    props: Object.keys(options.props),
    template: options.template,
    mounted() {
      cell.getTable().on("dataLoaded", () => this.$.appContext.app.unmount());
      cell.getTable().on("tableDestroyed", () => this.$.appContext.app.unmount());
    }
  });
  const div = document.createElement("div");
  const app = createApp(component, options.props).use(BootstrapVueNext).use(i18n).use(router).mount(div);
  return app.$el;
}

Usage example:

{
  title: "",
  headerSort: false,
  width: 66,
  formatter: (cell, formatterParams, onRendered) => {
    return formatterComponent(cell, {
      props: { data: cell.getData(), deleteService },
      template: `
      <div class="cell-buttons ps-2">
        <router-link :to="{ name: 'service', params: { id: data.id } }"><i class="icon-pencil"></i></router-link>
        <button @click="deleteService(data.id)" type="button"><i class="icon-trash"></i></button>
      </div>`
    });
  },
  cssClass: "p-0",
  vertAlign: "middle",
  frozen: true
}

Is this the right solution or is there another way?

Solution suggestion: It might be worth adding a parameter to the tabulator for the current vue instance so that you can use vue components inside the formatter without creating a mini vue app.

timothymarois commented 1 week ago

I would also agree to this, if tabulator can not handle vue components inside table columns, it limits its use-case significantly. I would love to use this package, but given that it can not handle components, I can't push this on my projects. The column data should be owned by the vue app, not the table package. Currently the table controls that and it makes it not as functional. No one is going to build custom JS to deal with editing values, we have great vue components that handle cases like menus and popovers to do edits ourselves in our UI components, we don't want the table system managing that. All we need is a table system that handles table data visually with resizing, column customization etc. This package is great, but over-engineered to use in modern frameworks. Example, columns should be customizable by template slots like PrimeVue has done and follows modern JS component practices. If I have to manage custom JS functions in my tables, its like using jQuery... cc @olifolkerd