Categories
Vue

Add Animation Effects Easily to our Vue App with the vue2-animate Library

Vue comes with animation and transition capabilities.

However, we have to add all the styles for the transitions ourselves.

The vue2-animate library makes this easier for us.

In this article, we’ll look at how to use the library to display animations.

Installation

We can install it by running:

npm i vue2-animate

Then we can import the CSS for the styles by writing:

import Vue from "vue";
import App from "./App.vue";
import "vue2-animate/dist/vue2-animate.min.css";
Vue.config.productionTip = false;

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

Adding the Animations

The vue2-animate library just provide the styles for some animation effects.

We just use it with the transition and transition-group components as we usually would.

For example, we write:

<template>
  <div>
    <button @click="add">add</button>
    <transition-group name="fadeLeft" tag="ul">
      <li v-for="item in items" :key="item.id">{{ item.text }}</li>
    </transition-group>
  </div>
</template>

<script>
import { v4 as uuidv4 } from "uuid";
export default {
  data() {
    return {
      items: Array(5)
        .fill()
        .map(() => ({
          id: uuidv4(),
          text: Math.random()
        }))
    };
  },
  methods: {
    add() {
      this.items.push({
        id: uuidv4(),
        text: Math.random()
      });
    }
  }
};
</script>

to apply the fadeLeft transition effect when we add an item.

Also, we can set the enter-active-class , name , and leave-active-class to the values that are supposed by the library:

<template>
  <div>
    <button @click="toggle = !toggle">toggle</button>
    <transition name="bounce" enter-active-class="bounceInLeft" leave-active-class="bounceOutRight">
      <p v-if="toggle">hello</p>
    </transition>
  </div>
</template>

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

This lets us control the animation for finely.

We can also set the animation duration with the style attribute:

<template>
  <div>
    <button @click="toggle = !toggle">toggle</button>
    <transition name="fade">
      <p v-if="toggle" style="animation-duration: 0.3s">hello</p>
    </transition>
  </div>
</template>

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

Use with Vue Router

We can add animation to route transitions with the bundled styles.

For example, we can write:

main.js

import Vue from "vue";
import App from "./App.vue";
import "vue2-animate/dist/vue2-animate.min.css";
import VueRouter from "vue-router";
Vue.use(VueRouter);
Vue.config.productionTip = false;
const Foo = { template: "<div>foo</div>" };
const Bar = { template: "<div>bar</div>" };

const routes = [
  { path: "/foo", component: Foo },
  { path: "/bar", component: Bar }
];

const router = new VueRouter({
  routes
});

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

App.vue

<template>
  <div>
    <router-link to="foo">foo</router-link>
    <router-link to="bar">bar</router-link>
    <transition
      enter-active-class="animated slideInRight"
      leave-active-class="animated slideOutLeft"
    >
      <router-view appear :key="$router.path"></router-view>
    </transition>
  </div>
</template>

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

We add the routes with the routes array.

And we add the router to our Vue instance.

Then in App.vue , we put the router-view in the transition component.

The appear prop is required for the animation.

The key is also needed to identify when the transition should be shown.

We also have the enter-active-class and leave-active-class for the transition added to add the effects.

Conclusion

The vue2-animate library has the styles for Vue transitions so we don’t have to write our own styles.

Categories
Ant Design Vue

Ant Design Vue — Customize Autocomplete and Cascade Dropdown

Ant Design Vue or AntD Vue, is a useful UI framework made for Vue.js.

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

Customize Autocomplete

We can customize our autocomplete input with various props.

The filter-options prop lets us change how choices are filtered:

<template>
  <a-auto-complete
    :data-source="dataSource"
    style="width: 200px"
    placeholder="input here"
    :filter-option="filterOption"
  />
</template>
<script>
export default {
  data() {
    return {
      dataSource: ["apple", "orange", "grape"]
    };
  },
  methods: {
    filterOption(input, option) {
      return (
        option.componentOptions.children[0].text
          .toUpperCase()
          .indexOf(input.toUpperCase()) >= 0
      );
    }
  }
};
</script>

We get the text input value which is the input parameter with the option.componentOptions.children[0].text property.

Then we compare both of them as uppercase.

If we return true , then it’s displayed in the dropdown.

Cascade Selection Box

We can add a cascade dropdown menu with the a-cascader component.

For example, we can write:

<template>
  <a-cascader :options="options" placeholder="Please select" @change="onChange"/>
</template>
<script>
export default {
  data() {
    return {
      options: [
        {
          value: "fruit",
          label: "Fruit",
          children: [
            {
              value: "apple",
              label: "Apple"
            }
          ]
        },
        {
          value: "drink",
          label: "Drink",
          children: [
            {
              value: "coffee",
              label: "Coffee"
            }
          ]
        }
      ]
    };
  },
  methods: {
    onChange(value) {
      console.log(value);
    }
  }
};
</script>

to add the options with the options reactive property.

We set that as the value of the options prop.

It emits the change event with the selected item.

We can add the change-on-select prop to emit the change event on select:

<template>
  <a-cascader :options="options" placeholder="Please select" change-on-select @change="onChange"/>
</template>
<script>
export default {
  data() {
    return {
      options: [
        {
          value: "fruit",
          label: "Fruit",
          children: [
            {
              value: "apple",
              label: "Apple"
            }
          ]
        },
        {
          value: "drink",
          label: "Drink",
          children: [
            {
              value: "coffee",
              label: "Coffee"
            }
          ]
        }
      ]
    };
  },
  methods: {
    onChange(value) {
      console.log(value);
    }
  }
};
</script>

Also, we can render the selected item in a custom way by populating the displayRender slot:

<template>
  <a-cascader :options="options" placeholder="Please select" change-on-select @change="onChange">
    <template slot="displayRender" slot-scope="{ labels, selectedOptions }">
      <span v-for="(label, index) in labels" :key="selectedOptions[index].value">
        <span v-if="index === labels.length - 1">
          {{ label }} (
          <a @click="e => handleAreaClick(e, label, selectedOptions[index])">
            {{
            selectedOptions[index].code
            }}
          </a>)
        </span>
        <span v-else @click="onChange">{{ label }} /</span>
      </span>
    </template>
  </a-cascader>
</template>
<script>
export default {
  data() {
    return {
      options: [
        {
          value: "fruit",
          label: "Fruit",
          code: 1,
          children: [
            {
              value: "apple",
              label: "Apple",
              code: 2
            }
          ]
        },
        {
          value: "drink",
          label: "Drink",
          code: 3,
          children: [
            {
              value: "coffee",
              label: "Coffee",
              code: 4
            }
          ]
        }
      ]
    };
  },
  methods: {
    onChange(value) {
      console.log(value);
    }
  }
};
</script>

selectedOptions[index] has the selected item.

labels have the label for each value.

Disable Items

We can disable items with the disabled property:

<template>
  <a-cascader :options="options" @change="onChange"/>
</template>
<script>
export default {
  data() {
    return {
      options: [
        {
          value: "fruit",
          label: "Fruit",
          children: [
            {
              value: "apple",
              label: "Apple"
            }
          ]
        },
        {
          value: "drink",
          label: "Drink",
          disabled: true,
          children: [
            {
              value: "coffee",
              label: "Coffee"
            }
          ]
        }
      ]
    };
  },
  methods: {
    onChange(value) {
      console.log(value);
    }
  }
};
</script>

Conclusion

We can customize our autocomplete component with many ways.

Also, Ant Design Vue comes with a cascade selection dropdown.

Categories
Ant Design Vue

Ant Design Vue — Cascade Selection Box and Checkbox

Ant Design Vue or AntD Vue, is a useful UI framework made for Vue.js.

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

Cascade Selection Box Default Value

We can set the default value of a cascade selection box with the default-value prop:

<template>
  <a-cascader :options="options" @change="onChange" :default-value="['fruit', 'apple']"/>
</template>
<script>
export default {
  data() {
    return {
      options: [
        {
          value: "fruit",
          label: "Fruit",
          children: [
            {
              value: "apple",
              label: "Apple"
            }
          ]
        },
        {
          value: "drink",
          label: "Drink",
          disabled: true,
          children: [
            {
              value: "coffee",
              label: "Coffee"
            }
          ]
        }
      ]
    };
  },
  methods: {
    onChange(value) {
      console.log(value);
    }
  }
};
</script>

We just pass in an array of values from top-level down to set it.

Also, we can add an icon on the right of the input by populating the suffixIcon prop:

<template>
  <a-cascader :options="options" @change="onChange">
    <a-icon slot="suffixIcon" type="smile" class="test"/>
  </a-cascader>
</template>
<script>
export default {
  data() {
    return {
      options: [
        {
          value: "fruit",
          label: "Fruit",
          children: [
            {
              value: "apple",
              label: "Apple"
            }
          ]
        },
        {
          value: "drink",
          label: "Drink",
          disabled: true,
          children: [
            {
              value: "coffee",
              label: "Coffee"
            }
          ]
        }
      ]
    };
  },
  methods: {
    onChange(value) {
      console.log(value);
    }
  }
};
</script>

Cascade Selection Field Names

We can set the field-names prop to set the property names of the value and label:

<template>
  <a-cascader
    :options="options"
    @change="onChange"
    :field-names="{ label: 'name', value: 'code', children: 'items' }"
  ></a-cascader>
</template>
<script>
export default {
  data() {
    return {
      options: [
        {
          code: "fruit",
          name: "Fruit",
          items: [
            {
              code: "apple",
              name: "Apple"
            }
          ]
        },
        {
          code: "drink",
          name: "Drink",
          children: [
            {
              code: "coffee",
              name: "Coffee"
            }
          ]
        }
      ]
    };
  },
  methods: {
    onChange(value) {
      console.log(value);
    }
  }
};
</script>

The object has the label , value , and children as the keys.

And we have the property names we want to set them to as the values.

Checkbox

We can add a checkbox to with the a-checkbox component:

<template>
  <a-checkbox @change="onChange">Checkbox</a-checkbox>
</template>
<script>
export default {
  methods: {
    onChange(e) {
      console.log(e.target.checked);
    }
  }
};
</script>

The change event is emitted when we check or uncheck the checkbox.

e.target.checked has the checked value.

Checkbox Group

We can add the a-checkbox-group component to add a group of checkboxes:

<template>
  <div>
    <div>
      <a-checkbox
        :indeterminate="indeterminate"
        :checked="checkAll"
        @change="onCheckAllChange"
      >Check all</a-checkbox>
    </div>
    <br>
    <a-checkbox-group v-model="checkedList" :options="plainOptions" @change="onChange"/>
  </div>
</template>
<script>
const plainOptions = ["Apple", "Pear", "Orange"];
const defaultCheckedList = ["Apple", "Orange"];
export default {
  data() {
    return {
      checkedList: defaultCheckedList,
      indeterminate: true,
      checkAll: false,
      plainOptions
    };
  },
  methods: {
    onChange(checkedList) {
      this.indeterminate =
        !!checkedList.length && checkedList.length < plainOptions.length;
      this.checkAll = checkedList.length === plainOptions.length;
    },
    onCheckAllChange(e) {
      Object.assign(this, {
        checkedList: e.target.checked ? plainOptions : [],
        indeterminate: false,
        checkAll: e.target.checked
      });
    }
  }
};
</script>

The indeterminate prop lets us set whether the checkbox is indeterminate.

a-checkbox-group has the checkbox group.

options has an array of options.

Conclusion

We can add the cascade selection box with various options.

Also, we can add the checkbox group.

Categories
Ant Design Vue

Ant Design Vue — Autocomplete

Ant Design Vue or AntD Vue, is a useful UI framework made for Vue.js.

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

Autocomplete Input

We can add an autocomplete input withn the a-auto-complete component:

<template>
  <a-auto-complete
    v-model="value"
    :data-source="dataSource"
    style="width: 200px"
    placeholder="input here"
    @select="onSelect"
    @search="onSearch"
    @change="onChange"
  />
</template>
<script>
export default {
  data() {
    return {
      value: "",
      dataSource: ["apple", "orange", "grape"]
    };
  },
  watch: {
    value(val) {
      console.log("value", val);
    }
  },
  methods: {
    onSearch(searchText) {
      this.dataSource = this.dataSource.filter(d => d.includes(searchText));
    },
    onSelect(value) {
      console.log("onSelect", value);
    },
    onChange(value) {
      console.log("onChange", value);
    }
  }
};
</script>

We add the v-model directive to bind the inputted value to a reactive property.

It also emits the select , search , and change events.

select is emitted when we select an item.

search is emitted when we are searching.

change is emitted when we change the input.

data-source has an array with the data source.

Also, we can display the autocomplete item by populate the dataSource slot:

<template>
  <div style="width: 250px">
    <a-auto-complete
      class="certain-category-search"
      dropdown-class-name="certain-category-search-dropdown"
      :dropdown-match-select-width="false"
      :dropdown-style="{ width: '300px' }"
      size="large"
      style="width: 100%"
      placeholder="input here"
      option-label-prop="value"
    >
      <template slot="dataSource">
        <a-select-opt-group v-for="group in dataSource" :key="group.title">
          <span slot="label">
            {{ group.title }}
            <a
              style="float: right"
              href="https://www.google.com/search?q=foo"
              target="_blank"
              rel="noopener noreferrer"
            >more</a>
          </span>
          <a-select-option v-for="opt in group.children" :key="opt.title" :value="opt.title">
            {{ opt.title }}
            <span class="certain-search-item-count">{{ opt.count }} people</span>
          </a-select-option>
        </a-select-opt-group>
        <a-select-option key="all" disabled class="show-all">
          <a
            href="https://www.google.com/search?q=baz"
            target="_blank"
            rel="noopener noreferrer"
          >View all results</a>
        </a-select-option>
      </template>
      <a-input>
        <a-icon slot="suffix" type="search" class="certain-category-icon"/>
      </a-input>
    </a-auto-complete>
  </div>
</template>
<script>
const dataSource = [
  {
    title: "Libraries",
    children: [
      {
        title: "foo",
        count: 10000
      },
      {
        title: "bar",
        count: 10600
      }
    ]
  },
  {
    title: "Articles",
    children: [
      {
        title: "baz",
        count: 100000
      }
    ]
  }
];
export default {
  data() {
    return {
      dataSource
    };
  }
};
</script>

We loop through the items in the dataSource reactive property to display the items.

Also, we set the class attribute to set the classes for our auto-complete.

The input can be customized. We just add the input we want to use inside the a-auto-complete component inside:

<template>
  <a-auto-complete
    :data-source="dataSource"
    style="width: 200px"
    @search="handleSearch"
    @select="onSelect"
  >
    <a-textarea
      placeholder="input here"
      class="custom"
      style="height: 50px"
      @keypress="handleKeyPress"
    />
  </a-auto-complete>
</template>
<script>
export default {
  data() {
    return {
      dataSource: ["apple", "orange", "grape"]
    };
  },
  methods: {
    onSelect(value) {
      console.log("onSelect", value);
    },
    handleSearch(value) {
      this.dataSource = this.dataSource.filter(d => d.includes(value));
    },
    handleKeyPress(ev) {
      console.log("handleKeyPress", ev);
    }
  }
};
</script>

We put it in the a-textarea inside the a-auto-complete to use a text area instead of a text input.

Conclusion

We can add autocomplete inputs our Vue app with Ant Design Vue.

Categories
Ant Design Vue

Getting Started with Ant Design Vue

Ant Design Vue or AntD Vue, is a useful UI framework made for Vue.js.

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

Getting Started

We can install AntD Vue by running:

npm i --save ant-design-vue

Then we can register the plugin by writing:

import Vue from "vue";
import App from "./App.vue";
import Antd from "ant-design-vue";
import "ant-design-vue/dist/antd.css";
Vue.use(Antd);
Vue.config.productionTip = false;

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

This will register the components and load the CSS.

Buttons

We can add buttons with AntD Vue by using the a-button component”

<template>
  <div id="app">
    <a-button type="primary">Primary</a-button>
  </div>
</template>

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

The type is the color type.

We can add a button group by writing:

<template>
  <div id="app">
    <a-button-group>
      <a-button>L</a-button>
      <a-button disabled>M</a-button>
      <a-button disabled>R</a-button>
    </a-button-group>
  </div>
</template>

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

We can add an icon with the icon prop:

<template>
  <div id="app">
    <a-button icon="search">Search</a-button>
  </div>
</template>

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

To make a button a block-level element, we can add the block prop:

<template>
  <div id="app">
    <a-button type="primary" block>Primary</a-button>
  </div>
</template>

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

Also, we can make it show a loading indicator with the loading prop:

<template>
  <div id="app">
    <a-button type="primary" loading>Loading</a-button>
  </div>
</template>

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

The size can be changed with the size prop:

<template>
  <div id="app">
    <a-button type="primary" size="large">Primary</a-button>
  </div>
</template>

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

Icon

AntD Vue comes with various icons.

For example, we can add one by writing:

<template>
  <div id="app">
    <a-icon type="step-backward"/>
  </div>
</template>

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

We use the a-icon component to add the icon.

There are many more we can add. The list is at https://www.antdv.com/components/icon/.

Grid

Ant Design Vue comes with its own layout grid. We can add it with the a-row and a-col components:

<template>
  <div id="app">
    <a-row>
      <a-col :span="12">col-12</a-col>
      <a-col :span="12">col-12</a-col>
    </a-row>
  </div>
</template>

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

We set the span prop to a value from 0 to 12 to make the layout.

It supports flexbox, and we can set the options with the justify and align props:

<template>
  <div id="app">
    <a-row type="flex" justify="center" align="top">
      <a-col :span="4">
        <p class="height-100">col-4</p>
      </a-col>
      <a-col :span="4">
        <p class="height-50">col-4</p>
      </a-col>
      <a-col :span="4">
        <p class="height-120">col-4</p>
      </a-col>
      <a-col :span="4">
        <p class="height-80">col-4</p>
      </a-col>
    </a-row>
  </div>
</template>

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

Now they are all centered.

Conclusion

We can use Ant Design Vue to create a good looking UI in our Vue app.