jiahengaa/BeeGridTable

Issues with importing as nested component.

Closed this issue · 4 comments

When component list imports BeeGridTable, everything works fine.
Now, component list-stories (in separate repository), wants to use component list (that uses BeeGridTable), then I see the error:
Screen Shot 2020-11-30 at 1 20 54 AM

Code for component list:

<template>
  <div @click='onClickRowHandler'>
    <BeeGridTable
      :columns='columnsData'
      :data='data'
      :showFilter='false'
      :showPager="showPagination"
      
      border
      highlight-row
      ref='selection'
    ></BeeGridTable>
  </div>
</template>

<script>
import Vue from "vue";
import BeeGridTable from "beegridtable";
import BeeLocale from "beegridtable/src/locale";
import "beegridtable/dist/styles/beegridtable.css";

import defaultProperties from "./defaultProperties";

Vue.use(BeeGridTable, {
  locale: BeeLocale,
  capture: true,
});

export default {
  name: 'list',
  components: {
    BeeGridTable, // Commenting out this line stops the above error, but still not usable in list-stories.
  },
  data(): {...},
  props: {...},
  computed: {...},
  methods: {...},
  mounted() {}
}
</script>

In src/main.js, (for repo of list component), I simply do:

import listComponent from './components/list/list.vue';
export default listComponent;

Code for component list-stories:

<template>
  <div>
    <list :rows='activeList'/>
  </div>
</template>
<script>
import list from 'list-component';
export default {
  name: "HelloWorld",
  props: {
    activeList: []
  },
  components: { list }
};
</script>

In src/main.js, (for repo of list-stories):

import Vue from "vue";
import App from "./App.vue";

Vue.config.productionTip = false;

new Vue({
  render: h => h(App)
}).$mount("#app");

Any advice on how to fix the bug.
Essentially, I am trying to figure out how to import BeeGridTable and export the wrapper component such that BeeGridTable is usable by caller component without explicitly importing BeeGridTable.

Well ! My understanding is that you have a custom component library, you need to encapsulate the BeeGridTable in it, and then use the custom component in your business project.
I made a project similar to your description. Beefor2 is similar to your component library, and beefor2demo is similar to your business project.
-- 1. Create a component list in the Beefor2 project

<template>
  <div @click="onClickRowHandler">
    <BeeGridTable
      :columns="columnsData"
      :data="data"
      :showFilter="canFilter"
      :showPager="showPagination"
      border
      highlight-row
      ref="selection"
    ></BeeGridTable>
  </div>
</template>


<script>
export default {
  name: "s-list",
  data() {
    return {};
  },
  props: {
    columns: {
      type: Array,
      default() {
        return [];
      },
    },
    rows: {
      type: Array,
      default() {
        return [];
      },
    },
    showFilter: {
      type: Boolean,
      default() {
        return false;
      },
    },
    showPager: {
      type: Boolean,
      default() {
        return false;
      },
    },
  },
  computed: {
    showPagination() {
      return this.showPager;
    },
    canFilter() {
      return this.showFilter;
    },
    data() {
      return this.rows;
    },
    columnsData() {
      return this.columns;
    },
  },
  methods: {
    onClickRowHandler() {
      console.log("clicked");
    },
  },
  mounted() {},
};
</script>

image

image

-- 2. In the entry file of the component library, it may be main.js in your project.

import Vue from "vue";
import App from "./App.vue";
import router from "./router";

import BeeGridTable from "beegridtable";
import BeeLocale from "beegridtable/src/locale";
import "beegridtable/dist/styles/beegridtable.css";

Vue.use(BeeGridTable, {
  locale: BeeLocale,
  capture: true,
});

Vue.config.productionTip = false;

new Vue({
  render: (h) => h(App),
  router,
}).$mount("#app");

image

-- 3.After you publish the component library, in your business project, you should reference your custom components like this

in main.js

import Vue from "vue";
import App from "./App.vue";

import beefor2 from "beefor2";
import "beefor2/dist/beefor2.css";

Vue.use(beefor2);

Vue.config.productionTip = false;

new Vue({
  render: (h) => h(App),
}).$mount("#app");

image

image

-- Final render normally!
image

If needed, I can upload the sample code.

For details, please see
beefor2
beefor2demo

Thank you so much @jiahengaa for writing so well detailed response.
The problem you understood is correct.
The solution you proposed works, but there is one problem.
The solution makes beefor2 a plugin as well (similar to how BeeGridTable is a plugin).
While, the product requirement is to make beefor2 a component (similar to how beefor2demo is a component).

Reason we need beefor2 as a component (and NOT a plugin) is because, the way our project is developed:

  1. Develop component A and test it
  2. Develop component B (which uses A) and test it
  3. Develop component C (which uses B) and is not aware about A and test it
  4. Develop component D (which uses C) and is not aware about A or B and test it.

Now, technically I can make all A,B,C,D as plugins and things will work the way you demoed (thanks for that 💯)

But, in our case, we already have a lot of code developed where C and D, etc are all components.
While, in this case, A (BeeGridTable) is a plugin.

Essentially how I see is, there are 2 options:

  1. Create a plugin B which should be installed in all testing environments C, D, E, ... etc
  2. Or, fork A, change its export mechanism to like a component and then use it.

Essentially how I see is, there are 2 options:

  1. Create a plugin B which should be installed in all testing environments C, D, E, ... etc
  2. Or, fork A, change its export mechanism to like a component and then use it.

In the case of N->...->C->B->A, make sure that when B->A, B can correctly import BeeGridTable and it's css style.