Categories
Top Vue Packages

Top Vue Packages for Adding Sliders, Highlighting Code, and More

In this article, we’ll look at the best packages for adding auto-scrolling, animating numbers, highlighting code, sliders, and displaying notifications.

vue-seamless-scroll

vue-seamless-scroll lets us add a component that automatically scrolls through its contents.

To use it, we run:

npm i vue-seamless-scroll

to install it.

Then we can write:

<template>
  <vue-seamless-scroll :data="listData" class="seamless-warp">
    <ul class="item">
      <li v-for="item in listData" :key="item">
        <span v-text="item"></span>
      </li>
    </ul>
  </vue-seamless-scroll>
</template>

<script>
import vueSeamlessScroll from "vue-seamless-scroll";

export default {
  components: {
    vueSeamlessScroll
  },
  data() {
    return {
      listData: Array(20)
        .fill()
        .map((_, i) => i)
    };
  }
};
</script>

We register the component.

And then we use the vue-seamless-scroll component.

We set the data prop to set the scroll data.

Then we loop through the entries we want to render.

Whatever is inside will be scrolled through continuously.

It’ll loop so it’ll keep scrolling from beginning to end until we navigate away from the page.

animated-number-vue

animated-number-vue lets us animate numbers in a Vue app.

To use it, we run:

npm i animated-number-vue

to install it.

Then we use it by writing:

<template>
  <animated-number :value="value" :formatValue="formatToPrice" :duration="300"/>
</template>
<script>
import AnimatedNumber from "animated-number-vue";

export default {
  components: {
    AnimatedNumber
  },
  data() {
    return {
      value: 1000
    };
  },
  methods: {
    formatToPrice(value) {
      return `$ ${value.toFixed(2)}`;
    }
  }
};
</script>

We use the animated-number component to display the animated number.

duration is the length of the animation.

value is the end number of the animation.

Vue Carousel 3d

Vue Carousel 3d is a 3D carousel for Vue apps.

To use it, we run:

npm i vue-carousel-3d

to install it.

Then we write:

main.js

import Vue from "vue";
import App from "./App.vue";
import Carousel3d from "vue-carousel-3d";

Vue.use(Carousel3d);
Vue.config.productionTip = false;

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

App.vue

<template>
  <div>
    <carousel-3d>
      <slide :index="0">Slide 1</slide>
      <slide :index="1">Slide 2</slide>
      <slide :index="2">Slide 3</slide>
    </carousel-3d>
  </div>
</template>

<script>
export default {};

to use it.

We use the carousel-3d with at least 3 slides.

The slide components house the slides.

Then we can flip through the slides.

Vue Toast Notification

Vue Toast Notification is a Vue plugin that lets us display toast in our Vue app.

To use it, we install it by running:

npm i vue-toast-notification

Then we can use it by writing:

main.js

import Vue from "vue";
import App from "./App.vue";
import VueToast from "vue-toast-notification";
import "vue-toast-notification/dist/theme-default.css";

Vue.use(VueToast);
Vue.config.productionTip = false;

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

App.vue

<template>
  <div id="app"></div>
</template>

<script>
export default {
  mounted() {
    this.$toast.open("hello!");
  }
};
</script>

We import the CSS and register the library.

Then we call this.$toast.open to open a basic notification.

We also display notifications for errors, warnings, and info messages.

Also, we can write:

<template>
  <div id="app"></div>
</template>

<script>
export default {
  mounted() {
    this.$toast.open({
      message: "Hello Vue",
      type: "success",
      duration: 5000,
      dismissible: true
    });
  }
};
</script>

to set our own options.

dismissible makes it dismissible.

message is the message.

type is the type of toast.

duration is the length of time to display the toast.

vue-hljs

vue-hljs lets us display code in our Vue app with syntax highlighting.

To use it, we run:

npm i vue-hljs

to install it.

Then we write:

main.js

import Vue from "vue";
import App from "./App.vue";
import vueHljs from "vue-hljs";
import "vue-hljs/dist/vue-hljs.min.css";

Vue.use(vueHljs);
Vue.config.productionTip = false;

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

App.vue

<template>
  <div id="app">
    <div v-highlight>
      <pre>
        <code class="javascript">const foo = 'bar'</code>
      </pre>
    </div>
  </div>
</template>

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

to display the code.

We just use the v-highlight directive to add the syntax highlighting.

Conclusion

vue-hljs lets us add syntax highlighting to our code display.

vue-seamless-scroll makes scrolling automatic.

Vue Toast Notification displays notifications in various formats.

Vue Carousel 3d lets us add a 3D slider.

animated-number-vue animates numbers.

Categories
Top Vue Packages

Top Vue Packages for Adding Inputs, QR Codes, and Handle Events

Vue.js is an easy to use web app framework that we can use to develop interactive front end apps. In this article, we’ll look at how the best packages for adding inputs, focusing elements, adding QR codes, and emit and listen to global events.

Vue Cleave Component

Vue Cleave Component is an input component that lets us enter things like credit card numbers.

To use it, first, we run:

npm i vue-cleave-component

to install it.

Then we can use it by writing:

<template>
  <div>
    <cleave v-model="cardNumber" :options="options" class="form-control" name="card"></cleave>
  </div>
</template>

<script>
import Cleave from "vue-cleave-component";

export default {
  data() {
    return {
      cardNumber: null,
      options: {
        creditCard: true,
        delimiter: "-"
      }
    };
  },
  components: {
    Cleave
  }
};
</script>

We bind the inputted value to cardNumber with v-model .

options is the options we can set for the input.

creditCard set to true means that we let users enter credit card numbers.

delimiter is the delimiter between each chunk.

So we’ll see the dash between each set of 4 digits.

vue-bus

vue-bus is a Vue plugin to add an app-wide event bus to our app.

To use it, we install it by running:

npm i vue-bus

Then we can use it bu writing”

<template>
  <div></div>
</template>

<script>
export default {
  created() {
    this.$bus.on("add-todo", this.addTodo);
    this.$bus.once("once", () => console.log("fire once"));
    this.$bus.emit("once");
    this.$bus.emit("add-todo");
  },
  beforeDestroy() {
    this.$bus.off("add-todo", this.addTodo);
  },
  methods: {
    addTodo() {
      console.log("add todo");
    }
  }
};
</script>

We use the this.$bus.on method to listen to events.

this.$bus.once creates an event that’s fired only once.

emit emits an event.

this.$bus.off clears event listeners.

Vue MQ (MediaQuery)

Vue MQ (MediaQuery) lets us define breakpijts and build responsive designs easily.

To use it, we run:

npm i vue-mq

to install it.

Then we use it by writing:

main.js

import Vue from "vue";
import App from "./App.vue";
import VueMq from "vue-mq";

Vue.use(VueMq, {
  breakpoints: {
    sm: 450,
    md: 1250,
    lg: Infinity
  },
  defaultBreakpoint: "sm"
});
Vue.config.productionTip = false;

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

App.vue

<template>
  <div>
    <p>{{displayText}}</p>
  </div>
</template>

<script>
export default {
  computed: {
    displayText() {
      return this.$mq === "sm" ? "small" : "large";
    }
  }
};
</script>

We use the this.$mq property to check the size of the screen.

Then we can display text accordingly.

vue-focus

vue-focus is a reusable directive for letting us focus or blur an element.

To use it, we install it by running:

npm i vue-focus

Then we can use it by writing:

<template>
  <div>
    <input type="text" v-focus="focused" @focus="focused = true" @blur="focused = false">
    <button @click="focused = true">focus</button>
  </div>
</template>

<script>
import { mixin as focusMixin } from "vue-focus";

export default {
  mixins: [focusMixin],
  data() {
    return {
      focused: false
    };
  }
};
</script>

We have an input element, which we control the focus of with the v-focus directive.

The directive comes from registering the mixin.

The focus event is emitted when it’s focused, which we set focused to true when it’s emitted.

v-viewer

v-viewer is an image viewer component that can be used to display an image gallery.

To use it, we run:

npm i v-viewer

to install the package.

Then we write:

main.js

import Vue from "vue";
import App from "./App.vue";
import "viewerjs/dist/viewer.css";
import Viewer from "v-viewer";
Vue.use(Viewer);

Vue.config.productionTip = false;

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

We register the plugin and import the CSS.

App.vue

<template>
  <div>
    <viewer :images="images">
      <img v-for="src in images" :src="src" :key="src">
    </viewer>
  </div>
</template>

<script>
export default {
  data() {
    return {
      images: [
        "https://placekitten.com/200/200",
        "https://placekitten.com/201/201"
      ]
    };
  }
};
</script>

To add the image gallery with 2 images in it.

All we did is to use the viewer component and nest the images in it.

vue-qr

vue-qr is a plugin that lets us add a QR code to our app.

To use it, we install it by running:

npm i vue-qr

Then we can use it by writing:

<template>
  <div>
    <vue-qr text="Hello!" :callback="test" qid="test"></vue-qr>
  </div>
</template>

<script>
import VueQr from "vue-qr";

export default {
  components: { VueQr },
  methods: {
    test(dataUrl, id) {
      console.log(dataUrl, id);
    }
  }
};
</script>

We use the vue-qr component with the text we want to show when scanned into the text prop. The callback, which we pass in as the value of the callback prop is called when it’s loaded.

Conclusion

vue-qr is a QR code component. v-viewer lets us add an image viewer to our Vue app. vue-focus lets us control the focus of elements. Vue Cleave Component is an input component that lets users enter credit card numbers. vue-bus is an event bus library for Vue apps.

Categories
Testing

Jasmine — Timer, and Async Tests

Testing is an important part of JavaScript.

In this article, we’ll look at how to create more complex tests with Jasmine.

Testing JavaScript Timeout Functions

We can use Jasmine to test JavaScript timeout functions.

We can use the jasmine.clock() method to do this.

For instance, we can write:

describe("Manually ticking the Jasmine Clock", function () {
  let timerCallback;

  beforeEach(function () {
    timerCallback = jasmine.createSpy("timerCallback");
    jasmine.clock().install();
  });

  afterEach(function () {
    jasmine.clock().uninstall();
  });

  it("causes a timeout to be called synchronously", function () {
    setTimeout(function () {
      timerCallback();
    }, 100);

    expect(timerCallback).not.toHaveBeenCalled();
    jasmine.clock().tick(101);
    expect(timerCallback).toHaveBeenCalled();
  });
});

to create a timerCallback spy which we can watch.

We call jasmine.clock().install() to create the Jasmine timer.

And we call jasmine.clock().uninstall() to remove it at the end.

Then we call tick to change the time to what we want.

This way, we can check is our setTimeout callback is called.

Also, we can use it to test setInterval .

For instance, we can write:

describe("Manually ticking the Jasmine Clock", function () {
  let timerCallback;

  beforeEach(function () {
    timerCallback = jasmine.createSpy("timerCallback");
    jasmine.clock().install();
  });

  afterEach(function () {
    jasmine.clock().uninstall();
  });

  it("causes a timeout to be called synchronously", function () {
    setInterval(function () {
      timerCallback();
    }, 100);

    expect(timerCallback).not.toHaveBeenCalled();

    jasmine.clock().tick(101);
    expect(timerCallback.calls.count()).toEqual(1);

    jasmine.clock().tick(102);
    expect(timerCallback.calls.count()).toEqual(2);
  });
});

Like with the setTimeout test, we change the clock to the time we want with the tick method.

The time is changed relative to the time that the last tick is called.

Mocking the Date

We can use the mockDate method to mock the date we want.

For instance, we can write:

describe("Manually ticking the Jasmine Clock", function () {
  let timerCallback;

  beforeEach(function () {
    timerCallback = jasmine.createSpy("timerCallback");
    jasmine.clock().install();
  });

  afterEach(function () {
    jasmine.clock().uninstall();
  });

  it("mocks time time", function () {
    const baseTime = new Date(2020, 0, 1);

    jasmine.clock().mockDate(baseTime);

    jasmine.clock().tick(50);
    expect(new Date().getTime()).toEqual(baseTime.getTime() + 50);
  });
});

We et the baseTime to a Date instance and then use that with mockDate to set the date to when we want.

Then we call tick to move the time.

And then we used getTime to get the current time after tick is called.

Async Support

Jasmine supports testing async code.

We can test async code with:

describe("Using callbacks", function () {
  beforeEach(function (done) {
    setTimeout(function () {
      value = 0;
      done();
    }, 1);
  });

  it("supports sequential execution of async code", function (done) {
    value++;
    expect(value).toBeGreaterThan(0);
    done();
  });
});

We have the beforeEach callback that has a setTimeout function call.

We call done in the callback so that the test code is run.

In the test code, the callback takes the done parameter to let us call done to indicate that the test is done.

To fail a test, we can use done.fail to fail the test.

For instance, we can write:

describe("Using callbacks", function () {
  var foo = function (x, callBack1, callBack2) {
    if (x) {
      setTimeout(callBack1, 0);
    } else {
      setTimeout(callBack2, 0);
    }
  };

  it("should not call the second callBack", function (done) {
    foo(true,
      done,
      function () {
        done.fail("Second callback has been called");
      }
    );
  });
});

We called done.fail in the 2nd callback so that if it’s run, the test will fail.

Conclusion

We can run a variety of tests that has timers and async code with Jasmine.

Categories
Testing

Jasmine — Test Array, Strings, and Time-Dependent Code

Testing is an important part of JavaScript.

In this article, we’ll look at how to create more complex tests with Jasmine.

Array Checks

We can use the jasmine.arrayContaining method to check the content of the array.

For example, we can write:

describe("jasmine.arrayContaining", function () {
  let foo;

  beforeEach(function () {
    foo = [1, 2, 3];
  });

  it("matches arrays with some of the values", function () {
    expect(foo).toEqual(jasmine.arrayContaining([3, 1]));
    expect(foo).not.toEqual(jasmine.arrayContaining([6]));
  });

  describe("when used with a spy", function () {
    it("is useful when comparing arguments", function () {
      const callback = jasmine.createSpy('callback');
      callback([1, 2, 3, 4]);
      expect(callback)
        .toHaveBeenCalledWith(
          jasmine.arrayContaining([4, 2, 3])
        );
      expect(callback)
        .not
        .toHaveBeenCalledWith(
          jasmine.arrayContaining([5, 2])
        );
    });
  });
});

We have the jasmine.arrayContaining method to check for the numbers in the array.

It returns true if the array being checked has all the items in the array we passed into arrayContaining .

We can do the same with function arguments.

String Matches

We can use the jasmine.stringMatching to check if a string has a given substring or pattern.

For instance, we can write:

describe('jasmine.stringMatching', function () {
  it("matches as a regex", function () {
    expect({ foo: 'baz' })
      .toEqual({
        foo: jasmine.stringMatching(/^baz$/)
      });
    expect({ foo: 'foobarbaz' })
      .toEqual({
        foo: jasmine.stringMatching('bar')
      });
  });

  describe("when used with a spy", function () {
    it("is useful for comparing arguments", function () {
      const callback = jasmine.createSpy('callback');
      callback('foobarbaz');
      expect(callback)
        .toHaveBeenCalledWith(
          jasmine.stringMatching('baz')
        );
      expect(callback)
        .not
        .toHaveBeenCalledWith(
          jasmine.stringMatching(/^baz$/)
        );
    });
  });
});

We have the jasmine.stringMatching method with a regex and a string.

It lets us check for a regex pattern and a substring.

Asymmetric Equality Tester

We can create our own equality tester to do our check.

For instance, we can write:

describe("custom asymmetry", function () {
  const tester = {
    asymmetricMatch(actual) {
      return actual.includes('bar');
    }
  };

  it("dives in deep", function () {
    expect("foo,bar,baz,quux").toEqual(tester);
  });

  describe("when used with a spy", function () {
    it("is useful for comparing arguments", function () {
      const callback = jasmine.createSpy('callback');
      callback('foo,bar,baz');
      expect(callback).toHaveBeenCalledWith(tester);
    });
  });
});

We created our own tester object with the asymmericMatch method to check for what we want.

We just return a boolean expression with the condition we want to check.

Then we can use it with the toHaveBeenCalledWith or toEqual .

Therefore, we can check for the values and the arguments.

Jasmine Clock

We can test time-dependent code with the jasmine.clock method.

For example, we can write:

describe("custom asymmetry", function () {
  let timerCallback;

  beforeEach(function () {
    timerCallback = jasmine.createSpy("timerCallback");
    jasmine.clock().install();
  });

  afterEach(function () {
    jasmine.clock().uninstall();
  });

  it("causes a timeout to be called synchronously", function () {
    setTimeout(function () {
      timerCallback();
    }, 100);
    expect(timerCallback).not.toHaveBeenCalled();
    jasmine.clock().tick(101);
    expect(timerCallback).toHaveBeenCalled();
  });
});

We have the jasmine.clock().install() to make Jasmine mock the time.

Then we call jasmine.clock().uninstall() to remove the Jasmine clock.

In our test, we can change the time to what we want.

And then we can do our checks after some amount of time is elapsed.

Conclusion

We can test time-dependent code with Jasmine’s clock methods.

Also, we can check for array and string items with built-in functions.

And we can make our own matches to test what we want.

Categories
Testing

Jasmine — Spies and Matchers

Testing is an important part of JavaScript.

In this article, we’ll look at how to create more complex tests with Jasmine.

createSpy

We can call createSpy to stub a function.

They can be used to track arguments.

For instance, we can write:

describe("A spy", function () {
  let spy;

  beforeEach(function () {
    spy = jasmine.createSpy('spy');
    spy('foo', 'bar');
  });

  it("tracks that the spy was called", function () {
    expect(spy).toHaveBeenCalled();
  });
});

We created a spy with jasmine.createSpy .

It returns a function that can be watched with Jasmine.

So we can check if it has been called with toHaveBeenCalled .

createSpyObj

We can use the createSpyObj method to create a mock with multiple spies.

For instance, we can write:

describe("Multiple spies", function () {
  let person;

  beforeEach(function () {
    person = jasmine.createSpyObj('person', ['eat', 'drink', 'sleep', 'walk']);
    person.eat();
    person.drink();
    person.sleep(0);
    person.walk(0);
  });

  it("creates spies for each requested function", function () {
    expect(person.eat).toBeDefined();
    expect(person.drink).toBeDefined();
    expect(person.sleep).toBeDefined();
    expect(person.walk).toBeDefined();
  });
});

We called createSpyObj with the spy name as the first argument.

And the methods available in the spy object in the 2nd argument.

Then we can it and then check if the methods are defined

Matching and Spies

We can add more checks with more matches.

For instance, we can write:

describe("Tests", function () {
  it("matches any value", function () {
    expect({}).toEqual(jasmine.any(Object));
    expect(12).toEqual(jasmine.any(Number));
  });

  describe("when used with a spy", function () {
    it("is useful for comparing arguments", function () {
      const foo = jasmine.createSpy('foo');
      foo(12, () => true);
      expect(foo).toHaveBeenCalledWith(jasmine.any(Number), jasmine.any(Function));
    });
  });
});

We have can use toEqual to check the type of a value with jasmine.any .

We can use jasmine.any with toHaveBeenCalledWith to check if a spy is called with a given type of data.

jasmine.anything

We can use jasmine.anythibng to check if something matches anything that’s not null or undefined .

For instance, we can write:

describe("jasmine.anything", function () {
  it("matches anything", function () {
    expect(1).toEqual(jasmine.anything());
  });

  describe("when used with a spy", function () {
    it("is useful when the argument can be ignored", function () {
      const foo = jasmine.createSpy('foo');
      foo(12, 'bar');
      expect(foo).toHaveBeenCalledWith(12, jasmine.anything());
    });
  });
});

We have jasmine.anything() call to check if anything isn’t null or undefined .

Checking Object Structure

We can check for object structure with the jasmine.objectContaining method.

For instance, we can write:

describe("jasmine.objectContaining", function () {
  let foo;

  beforeEach(function () {
    foo = {
      a: 1,
      b: 2,
      bar: "baz"
    };
  });

  it("matches objects with key-value pairs", function () {
    expect(foo).toEqual(jasmine.objectContaining({
      a: 1, bar: "baz"
    }));
  });

  describe("when used with a spy", function () {
    it("is useful for comparing arguments", function () {
      const callback = jasmine.createSpy('callback');

      callback({
        bar: "baz"
      });

      expect(callback)
        .toHaveBeenCalledWith(
          jasmine.objectContaining({
            bar: "baz"
          })
        );
    });
  });
});

We have the jasmine.objectContaining method to watch for object structure.

We just pass in the key-value pairs we want to check for.

It can be used with values and function arguments.

Conclusion

We can check for values and objects and watch for spies with various Jasmine methods.