Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to extend Vue component with default values for props and slots?

Tags:

vue.js

vuejs2

I'm using bootstrap-vue in my application, and I have a lot of tables, which all have the same boilerplate code. Here's an example of what that boilerplate might look like:

<b-table
  :items="someItemList"
  :busy="someItemList === null"
  :empty-text="$t('notFound')"
  :empty-filtered-text="$t('notFound')"
  no-sort-reset
  show-empty
  striped
  hover
>
  <div slot="table-busy" class="text-center my-3">
    <b-spinner class="align-middle"/>
  </div>
</b-table>

I would of course like to factor out this boilerplate into some sort of common module, like a custom component, so that my starting point for a new table would look something more like this:

<my-awesome-table :items="someItemList">
</my-awesome-table>

Ultimately, I would like my-awesome-table to act just like a normal b-table, but with all of this boilerplate already set, and where I can still set extra props and slots as needed.

However, I can't figure out a way to make this work. I've tried:

  • making a wrapper component, but then I struggle to expose all of the functionality of the underlying b-table
  • extending the b-table component, but then I struggle to set the prop and slot values as I've set them in my boilerplate template

How can I create a custom component which allows me to set default values for props and slots?

like image 647
thejonwithnoh Avatar asked Aug 14 '19 11:08

thejonwithnoh


People also ask

How do you pass a component as a prop Vue?

To pass a component as props and use it in a child component in Vue. js, we can use the component component. to add the component component. We set the is prop to the childComponent string which has the name of the component we want to render.

How do I upgrade my Vue components?

Using the $forceUpdate. This is one of the best ways to update a component because official Vue docs are recommending this method to update a component manually. Usually, Vue will react to changes in dependencies by updating the view.

How do I use props to pass data to child components in Vue?

The way it works is that you define your data on the parent component and give it a value, then you go to the child component that needs that data and pass the value to a prop attribute so the data becomes a property in the child component. You can use the root component (App.


1 Answers

In case you prefer templates, you could create a wrapper component like this:

  1. Assign v-bind to $attrs on b-table, which binds any attributes from the parent:
<b-table v-bind="$attrs" ...>
  1. Assign v-on to $listeners on b-table, which attaches any event listeners from the parent
<b-table v-on="$listeners" ...>
  1. Pass any slots to b-table:
<b-table ...>
  <template v-for="(_, slot) of $scopedSlots" v-slot:[slot]="scope">
    <slot :name="slot" v-bind="scope" />
  </template>
</b-table>

The result should look similar to this:

<template>
  <b-table
    your-prop-a
    your-prop-b
    your-prop-c
    v-bind="$attrs"
    v-on="$listeners"
  >
    <template v-for="(_, slot) of $scopedSlots" v-slot:[slot]="scope">
      <slot :name="slot" v-bind="scope" />
    </template>
  </b-table>
</template>

Edit Wrapper for b-table

like image 145
tony19 Avatar answered Oct 16 '22 12:10

tony19