A Single Component with different logic

VueJS: Vue 3 Composition API
Component Library: Ant Design Vue

Hello, everyone. How should I implement a single component with different logic? I have multiple remote search dropdown select boxes in a table row. For example, the first select call to /users API endpoint, and the other call different API endpoint and, so on. I’ve been thinking about passing a prop to a component and run a specific logic depending on the prop. Is it a good idea?

<template>
  <ATable
    :bordered="false"
    :columns="columns"
    :data-source="data"
    :pagination="{ position: ['topRight'] }"
  >
    <template #bodyCell="{ column, text }">
      <template v-if="column.key === 'group' || column.key === 'agent'">

        <!-- how to? -->
        <SingleSelectRemoteSearch /> 

      </template>
    </template>
    <template #title>Header</template>
    <template #footer>Footer</template>
  </ATable>
</template>

Hi @phyothiha
Yes it is possible to pass end points as a prop and make different api calls.

1 Like

Hi @phyothiha ,

Here’s a more in depth example, as I recently implemented something very similar to what you’re talking about:

I made a component called LiveEdit that allows a user to edit a string attribute of any object in my Django backend. It uses a dynamic API call method. I had to pass an endpoint url, attribute name, and attribute content (changed by user) as props to get it to work.

    async dynamicAPICall() {
      let outgoing_data = {}
      // Line to say if entry is empty string or any amount of whitespace, set it to null so DateField and other constrained fields stop complaining about format
      this.content =
        this.content != null && !this.content.match(/\S/) ? null : this.content



      // Fancy hacky code to dynamically set LHS of outgoing_data: Ex. LHS can be anything. name, phone, email, etc...
      outgoing_data[`${this.attribute}`] = this.content // ! THIS IS THE IMPORTANT PART



      // console.log(this.endpoint)
      // console.log(outgoing_data)
      try {
        // eslint-disable-next-line no-unused-vars
        const response = await axios({
          method: 'PATCH',
          url: this.endpoint,
          data: outgoing_data,
        })
        this.$emit('refresh')
      } catch (error) {
        this.$logAndAlert(error)
      }
    },

And now how it’s used in a template. Note how I have to pass the instance’s ID in the url as well

<template #revenue_date="{ item }">
...
    <LiveEdit
        :initialContent="item.revenue_date"
        :endpoint="`/api/v1/rev_rec_proj_miles/${item.rev_rec_project_milestones_pct_cmp_id}/`"
        :attribute="'date'"
    />
...
</template>

Obviously there’s a lot of missing code here, like how I set up props and render the LiveEdit component itself, but copy pasting is tedious and I want to keep this answer clean.

I have also implemented a LiveCheck (checkbox) and intend to implement a LiveDrop (dropdown), which I think is what you’re trying to do here. This holy trinity can be used to make your applications highly interactive and seamless to the user.

If you have any other questions or want me to go into more detail, don’t hesitate to ask! I’m actually still stuck on a question I asked on this forum a while back, where I’m trying to make these custom components cooperate with a CSmartTable filter to no avail (look at CoreUI CSmartTable not playing nice with custom component in template). Vue seems to struggle with re-rendering and re-computing things when they are in nested objects…

1 Like