Categories
Buefy

Buefy — Customize Table

Buefy is a UI framework that’s based on Bulma.

In this article, we’ll look at how to use Buefy in our Vue app.

Checkable Rows

We can add the checkable prop to make the rows checkable.

To do that, we write:

<template>
  <div id="app">
    <b-table
      :data="data"
      :columns="columns"
      :checked-rows.sync="checkedRows"
      :is-row-checkable="(row) => row.id !== 3 "
      checkable
      checkbox-position="left"
    >
      <template slot="bottom-left">
        <b>Total checked</b>
        : {{ checkedRows.length }}
      </template>
    </b-table>
  </div>
</template>

<script>
export default {
  name: "App",
  data() {
    const data = [
      {
        id: 1,
        first_name: "james",
        last_name: "smith"
      },
      {
        id: 2,
        first_name: "mary",
        last_name: "jones"
      },
      {
        id: 3,
        first_name: "alex",
        last_name: "wong"
      }
    ];
    return {
      checkedRows: [],
      data,
      columns: [
        {
          field: "id",
          label: "ID",
          width: "40",
          numeric: true
        },
        {
          field: "first_name",
          label: "First Name"
        },
        {
          field: "last_name",
          label: "Last Name"
        }
      ]
    };
  }
};
</script>

The checkbox-position sets the checkbox position.

is-row-checkable lets us set which rows are checkable with a function. The row parameter is a row object we check.

checked-rows has an array of checked rows.

Searchable

We can add the searchable property to our column objects to make the column searchable.

For example, we can write:

<template>
  <div id="app">
    <b-table :data="data">
      <template v-for="column in columns">
        <b-table-column :key="column.id" v-bind="column">
          <template slot="searchable" slot-scope="props">
            <b-input v-model="props.filters[props.column.field]" placeholder="Search..."/>
          </template>
          <template v-slot="props">{{ props.row[column.field] }}</template>
        </b-table-column>
      </template>
    </b-table>
  </div>
</template>

<script>
export default {
  name: "App",
  data() {
    const data = [
      {
        id: 1,
        first_name: "james",
        last_name: "smith"
      },
      {
        id: 2,
        first_name: "mary",
        last_name: "jones"
      },
      {
        id: 3,
        first_name: "alex",
        last_name: "wong"
      }
    ];
    return {
      checkedRows: [],
      data,
      columns: [
        {
          field: "id",
          label: "ID",
          width: "40",
          numeric: true
        },
        {
          field: "first_name",
          label: "First Name",
          searchable: true
        },
        {
          field: "last_name",
          label: "Last Name",
          searchable: true
        }
      ]
    };
  }
};
</script>

We will see a search box on any column that has the searchable property set to true .

The search box is added by populating the searchable slot with our own search box.

props.filters[props.column.field] is the search term that Buefy will look for.

Pagination and Sorting

We can add pagination with the paginated and per-page props:

<template>
  <div id="app">
    <b-table :data="data" :columns="columns" paginated :per-page="2"></b-table>
  </div>
</template>

<script>
export default {
  name: "App",
  data() {
    const data = [
      {
        id: 1,
        first_name: "james",
        last_name: "smith"
      },
      {
        id: 2,
        first_name: "mary",
        last_name: "jones"
      },
      {
        id: 3,
        first_name: "alex",
        last_name: "wong"
      }
    ];
    return {
      data,
      columns: [
        {
          field: "id",
          label: "ID",
          width: "40",
          numeric: true
        },
        {
          field: "first_name",
          label: "First Name"
        },
        {
          field: "last_name",
          label: "Last Name"
        }
      ]
    };
  }
};
</script>

We add the paginated prop to enable pagination.

And we set the per-page prop to set the number of items per page.

To add sorting, we can add the default-sort prop and the sortable property to the column to make a column sortable:

<template>
  <div id="app">
    <b-table :data="data" :columns="columns" default-sort="first_name" default-sort-direction="asc"></b-table>
  </div>
</template>

<script>
export default {
  name: "App",
  data() {
    const data = [
      {
        id: 1,
        first_name: "james",
        last_name: "smith"
      },
      {
        id: 2,
        first_name: "mary",
        last_name: "jones"
      },
      {
        id: 3,
        first_name: "alex",
        last_name: "wong"
      }
    ];
    return {
      data,
      columns: [
        {
          field: "id",
          label: "ID",
          width: "40",
          numeric: true
        },
        {
          field: "first_name",
          label: "First Name",
          sortable: true
        },
        {
          field: "last_name",
          label: "Last Name",
          sortable: true
        }
      ]
    };
  }
};
</script>

Conclusion

We can add pagination, make the rows checkable, and make columns sortable with Buefy.

Categories
Buefy

Buefy — Tables

Buefy is a UI framework that’s based on Bulma.

In this article, we’ll look at how to use Buefy in our Vue app.

Table

Buefy comes with a table component. It can be used to display data responsively.

We can use the b-table to add a simple table to our Vue app:

<template>
  <div id="app">
    <b-table :data="data" :columns="columns"></b-table>
  </div>
</template>

<script>
export default {
  name: "App",
  data() {
    return {
      data: [
        {
          id: 1,
          first_name: "james",
          last_name: "smith"
        },
        {
          id: 2,
          first_name: "mary",
          last_name: "jones"
        },
        {
          id: 3,
          first_name: "alex",
          last_name: "wong"
        }
      ],
      columns: [
        {
          field: "id",
          label: "ID",
          width: "40",
          numeric: true
        },
        {
          field: "first_name",
          label: "First Name"
        },
        {
          field: "last_name",
          label: "Last Name"
        }
      ]
    };
  }
};
</script>

The data prop has an array of data.

columns has the column definitions. The field property has the property name. label has the column label.

The width has the column width.

Custom Columns

We can add the b-table-column column to add the columns. For example, we can write:

<template>
  <div id="app">
    <b-table :data="data" :columns="columns">
      <b-table-column field="id" label="ID" width="40" numeric v-slot="props">{{ props.row.id }}</b-table-column>

    <b-table-column
        field="first_name"
        label="First Name"
        v-slot="props"
      >{{ props.row.first_name }}</b-table-column>

    <b-table-column field="last_name" label="Last Name" v-slot="props">{{ props.row.last_name }}</b-table-column>
    </b-table>
  </div>
</template>

<script>
export default {
  name: "App",
  data() {
    return {
      data: [
        {
          id: 1,
          first_name: "james",
          last_name: "smith"
        },
        {
          id: 2,
          first_name: "mary",
          last_name: "jones"
        },
        {
          id: 3,
          first_name: "alex",
          last_name: "wong"
        }
      ],
      columns: [
        {
          field: "id",
          label: "ID",
          width: "40",
          numeric: true
        },
        {
          field: "first_name",
          label: "First Name"
        },
        {
          field: "last_name",
          label: "Last Name"
        }
      ]
    };
  }
};
</script>

We added the b-table-column to add the columns.

props.row has the row object.

Custom Table

b-table has many props that we can change.

For example, we can write:

<template>
  <div id="app">
    <b-table
      :data="data"
      :columns="columns"
      bordered
      striped
      narrowed
      hoverable
      loading
      focusable
      mobile-cards
    ></b-table>
  </div>
</template>

<script>
export default {
  name: "App",
  data() {
    return {
      data: [
        {
          id: 1,
          first_name: "james",
          last_name: "smith"
        },
        {
          id: 2,
          first_name: "mary",
          last_name: "jones"
        },
        {
          id: 3,
          first_name: "alex",
          last_name: "wong"
        }
      ],
      columns: [
        {
          field: "id",
          label: "ID",
          width: "40",
          numeric: true
        },
        {
          field: "first_name",
          label: "First Name"
        },
        {
          field: "last_name",
          label: "Last Name"
        }
      ]
    };
  }
};
</script>

to add the props.

bordered adds the borders.

striped makes the rows striped.

narrowed makes the rows shorter.

hoverable makes the rows hoverable.

loading shows the loading indicator over the table.

focusable makes the table focusable.

mobile-cards makes the mobile cards.

Selection

We can set the selected prop to make a row highlightable.

For example, we can write:

<template>
  <div id="app">
    <b-table :data="data" :columns="columns" :selected.sync="selected"></b-table>
  </div>
</template>

<script>
export default {
  name: "App",
  data() {
    const data = [
      {
        id: 1,
        first_name: "james",
        last_name: "smith"
      },
      {
        id: 2,
        first_name: "mary",
        last_name: "jones"
      },
      {
        id: 3,
        first_name: "alex",
        last_name: "wong"
      }
    ];
    return {
      selected: data[1],
      data,
      columns: [
        {
          field: "id",
          label: "ID",
          width: "40",
          numeric: true
        },
        {
          field: "first_name",
          label: "First Name"
        },
        {
          field: "last_name",
          label: "Last Name"
        }
      ]
    };
  }
};
</script>

We added the selected prop with the reference to the row we want to highlight. Then we’ll see that it’s highlighted.

Conclusion

Buefy comes with a b-table component to let us add a table to a Vue app.

Categories
Vue

Scroll to the Bottom of a Div with Vue.js

There are various ways to scroll to a bottom of a div with Vue.js

In this article, we’ll look at how to scroll to the bottom of a div with Vue.js

Get the div and Set Scroll Top

We can set the scrollTop property of a DOM element to its scrollHeight so that scroll it to the bottom.

scrollHeight has the height of the element.

For example, we can write:

<template>
  <div id="app">
    <button @click="scrollToBottom">scroll to bottom</button>
    <div id="container" style="height: 200px; overflow-y: scroll">
      <p v-for="n in 100" :key="n">{{n}}</p>
    </div>
  </div>
</template>

<script>
export default {
  name: "App",
  methods: {
    scrollToBottom() {
      const container = this.$el.querySelector("#container");
      container.scrollTop = container.scrollHeight;
    }
  }
};
</script>

In the scrollToBottom method, we get the div with the ID container .

And we set its scrollTop property and set it to the scrollHeight to scroll to the bottom of the div.

We can also get an element from the ref.

To do that, we write:

<template>
  <div id="app">
    <button @click="scrollToBottom">scroll to bottom</button>
    <div id="container" ref="container" style="height: 200px; overflow-y: scroll">
      <p v-for="n in 100" :key="n">{{n}}</p>
    </div>
  </div>
</template>

<script>
export default {
  name: "App",
  methods: {
    scrollToBottom() {
      const container = this.$refs.container;
      container.scrollTop = container.scrollHeight;
    }
  }
};
</script>

We assign the ref to the container by adding the ref attribute.

Then in the scrollToBottom method, we get the container with this.$refs.container and set the scrollHeight the same way.

Scroll to an Element with a Given Selector

We can scroll to an element with the given selector with plain JavaScript.

We can get the element by using this.$el.querySelector method and call the scrollIntoView method to scroll it into view:

<template>
  <div id="app">
    <button @click="scrollIntoView">scroll into view</button>
    <div id="container" ref="container" style="height: 200px; overflow-y: scroll">
      <p v-for="n in 100" :key="n" :id="`num-${n}`">{{n}}</p>
    </div>
  </div>
</template>

<script>
export default {
  name: "App",
  methods: {
    scrollIntoView() {
      const el = this.$el.querySelector("#num-80");
      if (el) {
        el.scrollIntoView();
      }
    }
  }
};
</script>

We set the id for each element inside the div with ID container .

Then in the scrollIntoView method, we get the element with this.$el.querySelector method.

And then we call scrollIntoView method if it’s found.

We can also assign it a ref and call scrollIntoView on it.

To do that, we write:

<template>
  <div id="app">
    <button @click="scrollIntoView">scroll into view</button>
    <div id="container" style="height: 200px; overflow-y: scroll">
      <p v-for="n in 100" :key="n" :ref="`num-${n}`">{{n}}</p>
    </div>
  </div>
</template>

<script>
export default {
  name: "App",
  methods: {
    scrollIntoView() {
      const [el] = this.$refs["num-80"];
      if (el) {
        el.scrollIntoView();
      }
    }
  }
};
</script>

We get the refs and access the element with the ref by its index.

Then we call scrollIntoView on it.

Change Scrolling Behavior

We can change the behavior when we call scrollIntoView . To do that, we pass in an object to change the scroll behavior:

<template>
  <div id="app">
    <button @click="scrollIntoView">scroll into view</button>
    <div id="container" style="height: 200px; overflow-y: scroll">
      <p v-for="n in 100" :key="n" :ref="`num-${n}`">{{n}}</p>
    </div>
  </div>
</template>

<script>
export default {
  name: "App",
  methods: {
    scrollIntoView() {
      const [el] = this.$refs["num-80"];
      if (el) {
        el.scrollIntoView({ behavior: "smooth", block: "end" });
      }
    }
  }
};
</script>

behavior changes the scrolling behavior.

'smooth' means smooth scrolling.

block determines when to stop scrolling. 'end' means we stop scrolling when the element we scroll to is visible at the bottom of the container.

Conclusion

We can scroll to the bottom of a div or a given element with the Vue.js by getting the element in various ways and calling native DOM methods.

Categories
Vue

Add a Hamburger Menu to a Vue App with the vue-burger-menu Library

The vue-burger-menu library lets us add a hamburger menu to our Vue app easily.

In this article, we’ll look at how to add the menu using the vue-burger-menu library.

Installation

We can install the library by running:

npm i vue-burger-menu

or

yarn add vue-burger-menu

Add the Menu

Once we installed the library, we add the menu with the Menu component.

We write:

<template>
  <div id="app">
    <Slide>
      <a id="home" href="#">
        <span>Home</span>
      </a>
    </Slide>
  </div>
</template>

<script>
import { Slide } from "vue-burger-menu";

export default {
  name: "App",
  components: {
    Slide
  }
};
</script>

to add a simple menu.

Animations

We can change the animation by adding a menu with a different component.

They include:

  • Slide
  • ScaleDown
  • ScaleRotate
  • Reveal
  • Push
  • PushRotate

For example, we can write:

<template>
  <div id="app">
    <ScaleDown>
      <a id="home" href="#">
        <span>Home</span>
      </a>
    </ScaleDown>
  </div>
</template>

<script>
import { ScaleDown } from "vue-burger-menu";

export default {
  name: "App",
  components: {
    ScaleDown
  }
};
</script>

to add a hamburger menu with the scale down effect with the ScaleDown component.

Properties

There are various props we can change to customize our menu.

We can add the right prop to make the menu side from the right instead of the left:

<template>
  <div id="app">
    <Slide right>
      <a id="home" href="#">
        <span>Home</span>
      </a>
    </Slide>
  </div>
</template>

<script>
import { Slide } from "vue-burger-menu";

export default {
  name: "App",
  components: {
    Slide
  }
};
</script>

Also, we can change the width of the menu with the width prop:

<template>
  <div id="app">
    <Slide :width="400">
      <a id="home" href="#">
        <span>Home</span>
      </a>
    </Slide>
  </div>
</template>

<script>
import { Slide } from "vue-burger-menu";

export default {
  name: "App",
  components: {
    Slide
  }
};
</script>

The open state can be changed with the isOpen prop:

<template>
  <div id="app">
    <Slide isOpen>
      <a id="home" href="#">
        <span>Home</span>
      </a>
    </Slide>
  </div>
</template>

<script>
import { Slide } from "vue-burger-menu";

export default {
  name: "App",
  components: {
    Slide
  }
};
</script>

The menu also emits some events. openMenu is emitted when the menu is opened.

closeMenu is emitted when the menu is closed.

For example, we can use them by writing:

<template>
  <div id="app">
    <Slide @openMenu="openMenu" @closeMenu="closeMenu">
      <a id="home" href="#">
        <span>Home</span>
      </a>
    </Slide>
  </div>
</template>

<script>
import { Slide } from "vue-burger-menu";

export default {
  name: "App",
  components: {
    Slide
  },
  methods: {
    openMenu() {
      console.log("menu open");
    },
    closeMenu() {
      console.log("menu close");
    }
  }
};
</script>

We can disable close on outside click by using the disableOutsideClick prop:

<template>
  <div id="app">
    <Slide disableOutsideClick>
      <a id="home" href="#">
        <span>Home</span>
      </a>
    </Slide>
  </div>
</template>

<script>
import { Slide } from "vue-burger-menu";

export default {
  name: "App",
  components: {
    Slide
  }
};
</script>

Similarly, we can disable close on escape with the disableEsc prop:

<template>
  <div id="app">
    <Slide disableEsc>
      <a id="home" href="#">
        <span>Home</span>
      </a>
    </Slide>
  </div>
</template>

<script>
import { Slide } from "vue-burger-menu";

export default {
  name: "App",
  components: {
    Slide
  }
};
</script>

We can turn off the overlay with the noOverlay prop:

<template>
  <div id="app">
    <Slide noOverlay>
      <a id="home" href="#">
        <span>Home</span>
      </a>
    </Slide>
  </div>
</template>

<script>
import { Slide } from "vue-burger-menu";

export default {
  name: "App",
  components: {
    Slide
  }
};
</script>

Conclusion

We can add a hamburger menu with the vue-burger-menu library to a Vue app.

Categories
Vue

Add a Good Looking Scrollbar to our App with the vue-perfect-scrollbar Library

The vue-perfect-scrollbar library lets us add a scrollbar easily into our Vue app.

In this article, we’ll look at how to add a scroll bar to our Vue app with it.

Installation

We can install the library by running:

npm install vue-perfect-scrollbar

Adding the Scrollbar

We can add a scrollbar with the library by writing:

<template>
  <div id="app">
    <VuePerfectScrollbar
      style="height: 300px"
      class="scroll-area"
      v-once
      :settings="settings"
      @ps-scroll-y="scrollHandle"
    >
      <p v-for="n in 100" :key="n">{{n}}</p>
    </VuePerfectScrollbar>
  </div>
</template>

<script>
import VuePerfectScrollbar from "vue-perfect-scrollbar";

export default {
  name: "App",
  components: {
    VuePerfectScrollbar
  },
  data() {
    return {
      settings: {
        maxScrollbarLength: 60
      }
    };
  },
  methods: {
    scrollHandle(evt) {
      console.log(evt);
    }
  }
};
</script>

We add the VuePerfectScrollbar component to our Vue app after we registered it.

The v-once directive renders the elements and components inside once only.

settings has the settings. We set the maxScrollbarLength to set the length of the scrollbar.

It emits the ps-scroll-y event to run a method when we scroll.

Options

We can set many other options.

wheelSpeed sets the scroll speed of the mouse wheel.

wheelPropagation is a boolean to let us set whether to propagate mouse wheel events.

swipeEasing is a boolean to add easing to swipes.

minScrollbarLength is a number to set the min scrollbar length.

scrollingThreshold is a number to set the threshold for applying the ps--scrolling-x and ps--scrolling-y classes.

useBothWheelAxes is a boolean to enable vertical and horizontal scrolling.

suppressScrollX is a boolean to disable x-axis scrolling.

suppressScrollY is a boolean to disable y-axis scrolling.

scrollXMarginOffset is a number of pixels of the content that the content width can surpass the container width without enabling the x-axis scrollbar.

scrollYMarginOffset is a number of pixels of the content that the content width can surpass the container width without enabling the y-axis scrollbar.

Events

In addition to the ps-scroll-y event, the VuePerfectScrollbar component emits other events.

ps-scroll-x is emitted when we scroll horizontally.

ps-scroll-up is emitted when we scroll upward.

ps-scroll-down is emitted when we scroll downward.

ps-scroll-left is emitted when we scroll left.

ps-scroll-right is emitted when we scroll right.

ps-y-reach-start is emitted when we reach the start of the y-axis.

ps-y-reach-end is emitted when we reach the end of the y-axis.

ps-x-reach-start is emitted when we scroll to the start of the x-axis.

ps-x-reach-end is emitted when we scroll to the end of the x-axis.

Conclusion

The vue-perfect-scrollbar component lets us add a scrollbar and handle various events emitted when scrolling.