Vue Mixins for Component

Vue Mixins for Component demo by http://qcode.in

by Saqueib Ansari

HTML

<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.6/css/bootstrap.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.4.2/vue.js"></script>
<!-- Panel Template -->
<template id="panel">
  <div class="panel panel-default" :class="'panel-' + type">
    <div class="panel-heading">
      Vue Mixins ( state and closable mixin )
      <span class="pull-right">
        <a @click.prevent="toggle" href="">
          <i class="glyphicon" 
          :class="{
            'glyphicon-chevron-up': shown, 
            'glyphicon-chevron-down': !shown
            }">
          </i>
        </a>
      </span>
    </div>
    <div class="panel-body" v-show="shown">
      Panel content goes here
    </div>
  </div>
</template>

<!-- Button Template -->
<template id="btn">
  <button :disabled="loading" class="btn btn-default" :class="'btn-' + type">
    <slot>Button</slot>
  </button>
</template>

<!-- Alert Template -->
<template id="alert">
  <div v-if="shown" class="alert alert-success" :class="'alert-' + type" role="alert">
    <slot>Alert content</slot>
    <i class="pull-right glyphicon glyphicon-remove" @click="hide"></i>
  </div>
</template>

<!-- ------------------- -->

<div class="container">
  <div id="app">
    <h4 class="text-center">Vue Mixins 
    <br>
      <small>demo by 
        <a href="http://www.qcode.in" target="_blank">QCode.in</a>
      </small>
    </h4>

    <hr>
    
    <bs-panel type="info"></bs-panel>

    <hr>

    <bs-btn :loading="true">Loading...</bs-btn>
    <bs-btn type="success">I am button</bs-btn>
    <bs-btn type="danger">I am button too</bs-btn>

    <hr>
    
    <h5>I am closable </h5>
    <bs-alert type="success">Well done! You successfully read this.</bs-alert>
    <bs-alert type="danger">Oh snap! Change a few things up and try submitting again.
    </bs-alert>
    <bs-alert type="info">Heads up! This alert needs your attention, but it's not super important.</bs-alert>
    <bs-alert...

CSS

body {
  margin-top: 1rem
}

JavaScript

// Mixins
let stateableMixin = {
  props: ['type','loading']
}

// Closable
let closableMixin = {
  props: {
    isOpen: {
      default: true
    }
  },
  data: function() {
    return {
      shown: this.isOpen
    }
  },
  methods: {
    hide: function() {
      this.shown = false;
    },
    show: function() {
      this.shown = true;
    },
    toggle: function() {
      this.shown = !this.shown;
    }
  }
}

// Panel Component 
Vue.component('bs-panel', {
  template: '#panel',
  mixins: [stateableMixin, closableMixin]
});

// Button Component 
Vue.component('bs-btn', {
  template: '#btn',
  mixins: [stateableMixin]
});

// Alert Component 
Vue.component('bs-alert', {
  template: '#alert',
  mixins: [stateableMixin, closableMixin]
});


// Initialize Vue
new Vue({
  el: '#app'
})