Categories
Buefy

Buefy — Collapse Component

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.

Collapse

The collapse component is a component that lets us toggle items on and off.

To add it, we add the b-collapse component by writing:

<template>
  <section>
    <b-collapse :open="false">
      <button class="button is-primary" slot="trigger">Click me!</button>
      <div class="notification">
        <div class="content">
          <h3>Subtitle</h3>
          <p>
            Lorem ipsum dolor sit amet, consectetur adipiscing elit.
            Nulla accumsan, metus ultrices eleifend gravida, nulla nunc varius lectus, nec rutrum justo nibh eu lectus.
          </p>
        </div>
      </div>
    </b-collapse>
  </section>
</template>

<script>
export default {
  data() {
    return {};
  }
};
</script>

We add the b-collapse component with the button being in the trigger slot to use as the trigger for the collapse component.

Then content is anything outside the trigger slot in the b-collapse component.

Collapse Panel

We can add a tab panel by adding an element with the panel-tabs class:

<template>
  <section>
    <div class="block">
      <button class="button is-medium is-primary" [@click](http://twitter.com/click "Twitter profile for @click")="isOpen = !isOpen">Toggle</button>
    </div>

    <b-collapse class="panel" animation="slide" v-model="isOpen">
      <div slot="trigger" class="panel-heading" role="button" aria-controls="contentIdForA11y2">
        <strong>Title</strong>
      </div>
      <p class="panel-tabs">
        <a class="is-active">All</a>
        <a>Public</a>
        <a>Private</a>
      </p>
      <div class="panel-block">Lorem ipsum dolor sit amet, consectetur adipiscing elit.
        <br>Nulla accumsan, metus ultrices eleifend gravida, nulla nunc varius lectus, nec rutrum justo nibh eu lectus.
      </div>
    </b-collapse>
  </section>
</template>

<script>
export default {
  data() {
    return {
      isOpen: true
    };
  }
};
</script>

We have the b-collapse component with the p element with the panel-tabs class.

And we have the panel-block class on the div to display as the panel content.

Collapse Card

We can make a collapsible card by setting the class attribute of it to card .

The animation has the effect for the toggle.

For example, we can write:

<template>
  <section>
    <b-collapse class="card" animation="slide">
      <div slot="trigger" slot-scope="props" class="card-header" role="button">
        <p class="card-header-title">Component</p>
        <a class="card-header-icon">{{props.open ? '&#x2193;' : '&#x2191;'}}</a>
      </div>
      <div class="card-content">
        <div
          class="content"
        >Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus nec iaculis mauris.</div>
      </div>
      <footer class="card-footer">
        <a class="card-footer-item">OK</a>
        <a class="card-footer-item">Cancel</a>
      </footer>
    </b-collapse>
  </section>
</template>

<script>
export default {
  data() {
    return {};
  }
};
</script>

We have the elements with th card-header-title with the title.

card-header-icon has the icon.

And the card-content class is applied to the div with the content.

card-footer has the footer class, and card-footer-item is for the footer items.

props.open indicates whether the collapse component is expanded or not.

Collapse Position

We can place the b-collapse component anywhere we like.

For instance, we can place it inside another element by writing:

<template>
  <section>
    <div class="content">
      <h3>Subtitle</h3>
      <p>
        Lorem ipsum dolor sit amet, consectetur adipiscing elit.
        Ut vulputate semper dui.
      </p>
    </div>
    <b-collapse :open="false" position="is-bottom">
      <a slot="trigger" slot-scope="props">
        {{ !props.open ? 'All options' : 'Fewer options' }}
        {{props.open ? '&#x2191;': '&#x2193;' }}
      </a>
      <p>
        Lorem ipsum dolor sit amet, consectetur adipiscing elit.
        Nulla accumsan, metus ultrices eleifend gravida, nulla nunc varius lectus.
      </p>
    </b-collapse>
  </section>
</template>

We add the b-collapse component inside the div instead of keeping it standalone.

Conclusion

We can add a collapse component with Buefy to add a toggleable container to our Vue app.

Categories
Buefy

Buefy — Carousels

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.

Carousel Progress

We can show a progress bar on top of the carousel to indicate its progress.

For example, we can write:

<template>
  <b-carousel progress progressType="is-primary">
    <b-carousel-item v-for="(carousel, i) in carousels" :key="i">
      <section>
        <div class="hero-body has-text-centered">
          <h1 class="title">{{carousel.text}}</h1>
        </div>
      </section>
    </b-carousel-item>
  </b-carousel>
</template>

<script>
export default {
  data() {
    return {
      carousels: [{ text: "Slide 1" }, { text: "Slide 2" }, { text: "Slide 3" }]
    };
  }
};
</script>

to add the progress prop to enable the progress bar.

And progressType styles the progress bar.

Carousel Indicator

The carousel’s slide indicator can also be changed.

For example, we can write:

<template>
  <b-carousel
    :indicator="indicator"
    :indicator-background="indicatorBackground"
    :indicator-inside="indicatorInside"
    :indicator-mode="indicatorMode"
    :indicator-position="indicatorPosition"
    :indicator-style="indicatorStyle"
  >
    <b-carousel-item v-for="(carousel, i) in carousels" :key="i">
      <section>
        <div class="hero-body has-text-centered">
          <h1 class="title">{{carousel.text}}</h1>
        </div>
      </section>
    </b-carousel-item>
  </b-carousel>
</template>

<script>
export default {
  data() {
    return {
      indicator: true,
      indicatorBackground: true,
      indicatorInside: true,
      indicatorMode: "hover",
      indicatorPosition: "is-top",
      indicatorStyle: "is-lines",
      carousels: [{ text: "Slide 1" }, { text: "Slide 2" }, { text: "Slide 3" }]
    };
  }
};
</script>

to add the indicator prop to enable the slide indicator.

indicatorBackground enables the indicator background.

indicatorInside adds the indicator inside the carousel.

indicatorMode sets how to interact with the indicator to change the slides.

indicatorPosition sets the indicator position.

indicatorStyle sets the indicator style.

Custom Carousel Indicators

We can create our own carousel indicator by populating the indicators slot.

For example, we can write:

<template>
  <b-carousel>
    <b-carousel-item v-for="(carousel, i) in carousels" :key="i">
      <section>
        <div class="hero-body has-text-centered">
          <h1 class="title">{{carousel.text}}</h1>
        </div>
      </section>
    </b-carousel-item>
    <template slot="indicators" slot-scope="props">
      <span>{{props.i}}</span>
    </template>
  </b-carousel>
</template>

<script>
export default {
  data() {
    return {
      carousels: [{ text: "Slide 1" }, { text: "Slide 2" }, { text: "Slide 3" }]
    };
  }
};
</script>

to add our own slide indicator by populating the indicators slot.

props.i has the index of the slide.

Custom Carousel With Card

We can add custom carousel with cards.

We can use the b-carousel-list component and populate the item slot with the card.

For example, we can write:

<template>
  <b-carousel-list v-model="test" :data="items" :items-to-show="2">
    <template slot="item" slot-scope="list">
      <div class="card">
        <div class="card-image">
          <figure class="image is-5by4">
            <a @click="info(list.index)">
              <img :src="list.image">
            </a>
          </figure>
          <b-tag type="is-danger" rounded style="position: absolute; top: 0;">
            <b>50%</b>
          </b-tag>
        </div>
        <div class="card-content">
          <div class="content">
            <p class="title is-6">{{ list.title }}</p>
            <p class="subtitle is-7">@abc</p>
            <div class="field is-grouped">
              <p class="control" v-if="list.rating">
                <b-rate :value="list.rating" show-score disabled/>
              </p>
              <p class="control" style="margin-left: auto">
                <button class="button is-small is-danger is-outlined">
                  <b-icon size="is-small" icon="heart"/>
                </button>
              </p>
            </div>
          </div>
        </div>
      </div>
    </template>
  </b-carousel-list>
</template>

<script>
export default {
  data() {
    return {
      items: [
        {
          title: "Slide 1",
          image: "https://buefy.org/static/img/placeholder-1280x960.png",
          rating: 4.5
        },
        {
          title: "Slide 2",
          image: "https://buefy.org/static/img/placeholder-1280x960.png",
          rating: 3.5
        },
        {
          title: "Slide 3",
          image: "https://buefy.org/static/img/placeholder-1280x960.png",
          rating: 5
        }
      ]
    };
  },
  methods: {
    info(value) {
      console.log(value);
    }
  }
};
</script>

We set the data prop to the items array so that we can set the data to the slides.

Inside the item slot, we have the figure with the image.

b-tag has the tag on the top left of the image.

The div with the card-content class has the content below the image.

b-rate has the rating stars.

Conclusion

There’re many ways to customize carousels with Buefy.

Categories
Buefy

Buefy — Buttons and Carousels

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.

Button Tags

We can change the tag of the button with the tag prop.

To use it, we can write:

<template>
  <section>
    <div class="buttons">
      <b-button>Button</b-button>
      <b-button tag="a" href="https://google.com" target="_blank">Anchor</b-button>
      <b-button tag="input" native-type="submit" value="Submit input"/>
    </div>
  </section>
</template>

<script>
export default {};
</script>

We can set tag to 'a' or 'input' to change the tag to those.

Button Router Link

We can also display links as router-links .

For example, we can write:

<template>
  <section>
    <div class="buttons">
      <b-button tag="router-link" to="/documentation" type="is-link">Docs</b-button>
    </div>
  </section>
</template>

<script>
export default {};
</script>

to render the b-button as a router-link component.

Carousel

Buefy comes with a carousel component.

For example, we can write:

<template>
  <b-carousel>
    <b-carousel-item v-for="(carousel, i) in carousels" :key="i">
      <section>
        <div class="hero-body has-text-centered">
          <h1 class="title">{{carousel.text}}</h1>
        </div>
      </section>
    </b-carousel-item>
  </b-carousel>
</template>

<script>
export default {
  data() {
    return {
      carousels: [{ text: "Slide 1" }, { text: "Slide 2" }, { text: "Slide 3" }]
    };
  }
};
</script>

to create a simple carousel with the b-carousel and b-carousel-item components.

b-carousel-item has the carousel items.

We can customize it with various props.

For example, we can write:

<template>
  <b-carousel
    v-model="carousel"
    animated
    has-drag
    autoplay
    pause-hover
    pause-info
    pause-info-type="is-primary"
    :interval="2000"
    repeat
    [@change](http://twitter.com/change "Twitter profile for @change")="info($event)"
  >
    <b-carousel-item v-for="(carousel, i) in carousels" :key="i">
      <section>
        <div class="hero-body has-text-centered">
          <h1 class="title">{{carousel.text}}</h1>
        </div>
      </section>
    </b-carousel-item>
  </b-carousel>
</template>

<script>
export default {
  data() {
    return {
      carousel: 1,
      carousels: [{ text: "Slide 1" }, { text: "Slide 2" }, { text: "Slide 3" }]
    };
  },
  methods: {
    info(e) {
      console.log(e);
    }
  }
};
</script>

to add some props to our b-carousel component to adjust it.

autoplay makes the carousel play automatically.

pause-hover makes it pause on hover.

has-drag makes the slides draggable.

pause-info-type sets the type for when it’s paused.

repeat makes the slides repeat after the loop is done.

v-model has the slide index.

animated adds some animation effect to the carousel.

The @change event handler is run when the slide changes.

Carousel Arrow

We can add the arrow to the carousel.

For example, we can write:

<template>
  <b-carousel
    :arrow="arrow"
    :repeat="arrowBoth"
    :arrow-hover="arrowHover"
    :icon-pack="iconPack"
    :icon-prev="iconPrev"
    :icon-next="iconNext"
    :icon-size="iconSize"
  >
    <b-carousel-item v-for="(carousel, i) in carousels" :key="i">
      <section>
        <div class="hero-body has-text-centered">
          <h1 class="title">{{carousel.text}}</h1>
        </div>
      </section>
    </b-carousel-item>
  </b-carousel>
</template>

<script>
export default {
  data() {
    return {
      arrow: true,
      arrowBoth: false,
      arrowHover: false,
      iconPack: "fa",
      iconPrev: "arrow-left",
      iconNext: "arrow-right",
      iconSize: "10px",
      carousels: [{ text: "Slide 1" }, { text: "Slide 2" }, { text: "Slide 3" }]
    };
  }
};
</script>

to use the arrow icons from Font Awesome 4.7.0 for our icons.

We set the icon class names with the icon-prev and icon-next props.

icon-pack sets the icon pack to use.

In index.html , we add the CSS by adding:

<link
      rel="stylesheet"
      href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css"
      integrity="sha384-wvfXpqpZZVQGK6TAh5PVlGOfQNHSoD2xbE+QkPxCAFlNEevoEH3Sl0sibVcOQVnN"
      crossorigin="anonymous"
    />

to the head tag.

Conclusion

We can render buttons our way and add carousels with Buefy.

Categories
Vue

Getting Started with vue-chartjs

The vue-chartjs library lets us add charts to a Vue app easily.

In this article, we’ll look at how to add charts to a Vue app with vue-chart.js

Installation

We can install the package with chart.js by running:

yarn add vue-chartjs chart.js

or:

npm install vue-chartjs chart.js --save

chart.js is a required dependency.

Creating our first Chart

Now we can create our first chart by creating a new component.

For example, we can write:

components/LineChart.vue

<script>
import { Line, mixins } from "vue-chartjs";
const { reactiveProp } = mixins;

export default {
  extends: Line,
  mixins: [reactiveProp],
  props: ["chartData", "options"],
  mounted() {
    this.renderChart(this.chartData, this.options);
  }
};
</script>

App.vue :

<template>
  <div>
    <line-chart :chart-data="data" :options="options"></line-chart>
  </div>
</template>

<script>
import LineChart from "./components/LineChart.vue";

export default {
  components: {
    LineChart
  },
  data() {
    return {
      data: {
        labels: ["Monday", "Tuesday", "Wednesday"],
        datasets: [
          {
            label: "# of Votes",
            data: [12, 19, 3],
            borderWidth: 1
          }
        ]
      },
      options: {
        responsive: true,
        maintainAspectRatio: false
      }
    };
  },
  methods: {}
};
</script>

We created the LineChart component to display a line chart.

It takes the chartData prop with the chart data.

And it takes an options prop with the chart options.

The extends property is set to Line so that we can display a line chart.

Then we can call this.renderChart to display the chart with the data and options.

In App.vue , we get the line-chart component that we created and use it to display our chart.

We pass in the data to the chart-data prop and the options to the options prop.

responsive makes the chart responsive.

And maintainAspectRatio keeps the aspect ratio of the chart the same regardless of screen size.

The label has the label for the chart.

labels has the x-axis labels.

backgroundColor is the background color for the fill between the line and the x-axis.

data has the y-axis values.

The reactiveProp mixin lets our chart responds to prop changes.

Now we should see a line chart displayed.

Events

The chart emits various emits. They include:

  • chart:render – emitted if the mixin performs a complete rerender
  • chart:destroy – emitted if the mixin deletes the chart object instance
  • chart:update – emitted if the mixin performs an update instead of a re-render
  • labels:update – emitted if new labels were set
  • xlabels:update emitted if new x-axis labels were set
  • ylabels:update – emitted if new y-axis labels were set

Own Watcher

We can add our own watcher with and call the this.$data._chart.update() method to update the chart when the chart data updates.

For example, we can write:

<script>
import { Line } from "vue-chartjs";

export default {
  extends: Line,
  props: ["chartData", "options"],
  mounted() {
    this.renderChart(this.chartData, this.options);
  },
  watch: {
    chartData() {
      this.$data._chart.update();
    }
  }
};
</script>

then we watch for changes to the chartData prop and update the chart accordingly.

This is useful is we want to transform the line chart in the line chart component.

Conclusion

We can add charts to a Vue app easily with the vue-chartjs component.

Categories
Vue

Add a Markdown Editor to our Vue App

We can add a Markdown editor to our Vue app easily.

With it, users can enter formatted text easily since it can easily be converted to HTML.

In this article, we’ll look at how to add a Markdown editor to our Vue app.

Mavon Editor

The Mavon editor package is an easy to use package for adding a Markdown editor.

We can install it by using NPM with:

npm install mavon-editor --save

Then we can use it by writing:

main.js

import Vue from "vue";
import App from "./App.vue";
import mavonEditor from "mavon-editor";
import "mavon-editor/dist/css/index.css";

Vue.use(mavonEditor);

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

App.vue

<template>
  <div class="mavonEditor">
    <no-ssr>
      <mavon-editor :toolbars="markdownOption" v-model="handbook"/>
    </no-ssr>
  </div>
</template>

<script>
export default {
  data() {
    return {
      markdownOption: {
        bold: true
      },
      handbook: "#### how to use mavonEditor in nuxt.js"
    };
  }
};
</script>

We add the mavonEditor plugin into the main.js so that we can use it our components.

The CSS is also required so that we can see correct styling.

It binds to a state property with the v-model directive so that we can use the entered text to do something else.

The editor is on the left side and the preview of the Markdown output is on the right side.

Options

It comes with various props that we can set to change the options.

value sets the initial value.

language sets the language for the editor. It can be:

  • zh-CN for simplified Chinese
  • zh-TW for traditional Chinese
  • en for English
  • fr for French
  • pt-BR for Brazilian Portugese
  • ru for Russian
  • de for German
  • ja for Japanese

fontSize sets the font size.

scrollStyle lets us scroll with the mouse wheel.

boxShadow lets us enable the box shadow for the editor.

boxShadowStyle sets the style for the box shadow.

teransition is a boolean to let is enable or disable transition effects.

previewBackground lets us set the preview pane’s background.

placeholder lets us set the placeholder.

editable lets us set whether the Markdown editor is editable.

imageFilter is a function for filtering for image files.

imageClick is a function that’s run when we click on an image.

toolbars lets us add a toolbar with an object.

For example, we can write:

<template>
  <div class="mavonEditor">
    <mavon-editor :toolbars="toolbars" v-model="handbook"/>
  </div>
</template>

<script>
export default {
  data() {
    return {
      toolbars: {
        bold: true,
        italic: true,
        header: true,
        underline: true,
        strikethrough: true,
        mark: true,
        superscript: true,
        subscript: true,
        quote: true,
        ol: true,
        ul: true,
        link: true,
        imagelink: true,
        code: true,
        table: true,
        fullscreen: true,
        readmodel: true,
        htmlcode: true,
        help: true,
        undo: true,
        redo: true,
        trash: true,
        save: true,
        navigation: true,
        alignleft: true,
        aligncenter: true,
        alignright: true,
        subfield: true,
        preview: true
      },
      handbook: "#### how to use mavonEditor in nuxt.js"
    };
  }
};
</script>

to add the toolbar icons.

We can do many things with it like any word processor.

Conclusion

Mavon editor is a useful Markdown editor that we can add to our Vue app.