Extending Element UI Components in Vue 2 with Vue.extend

Feb 13, 2025

Extending Element UI Components in Vue 2 with Vue.extend

Introduction

Element UI is a powerful and well-designed UI framework for Vue.js. It provides a rich set of components that cover most common UI needs. However, there are scenarios where default functionalities do not fit all requirements. Instead of rewriting components from scratch, we can extend them using Vue.extend in Vue 2.

In this article, we will explore how to extend an Element UI Autocomplete component to modify its behavior while keeping the existing features intact.

Why Extend Element UI Components?

While Element UI provides a great set of prebuilt components, sometimes we need to:

  • Override or extend existing methods.
  • Add new props or event handlers.
  • Customize the template structure.
  • Implement advanced interactions.

Instead of modifying Element UI’s source code or wrapping it in another component, Vue’s extend method allows us to inherit from an existing component while making targeted modifications.

Example: Extending el-autocomplete

We will extend the el-autocomplete component from Element UI to modify its focus and blur event handling while keeping all its existing functionalities.

Extended Component Code

Here’s an example of how we can extend el-autocomplete:

<template>  <div    class="el-autocomplete"    v-clickoutside="close"    aria-haspopup="listbox"    role="combobox"    :aria-expanded="suggestionVisible"    :aria-owns="id"  >    <el-input      ref="input"      v-bind="[$props, $attrs]"      @input="handleInput"      @change="handleChange"      @focus="handleFocus"      @blur="handleBlur"      @clear="handleClear"      @keydown.up.native.prevent="highlight(highlightedIndex - 1)"      @keydown.down.native.prevent="highlight(highlightedIndex + 1)"      @keydown.enter.native="handleKeyEnter"      @keydown.native.tab="close"    >      <template slot="prepend" v-if="$slots.prepend">        <slot name="prepend" />      </template>      <template slot="append" v-if="$slots.append">        <slot name="append" />      </template>      <template slot="prefix" v-if="$slots.prefix">        <slot name="prefix" />      </template>      <template slot="suffix" v-if="$slots.suffix">        <slot name="suffix" />      </template>    </el-input>    <AutocompleteSuggestion      visible-arrow      :class="[popperClass ? popperClass : '']"      :popper-options="popperOptions"      :append-to-body="popperAppendToBody"      ref="suggestions"      :placement="placement"      :id="id"    >      <li        v-for="(item, index) in suggestions"        :key="index"        :class="{'highlighted': highlightedIndex === index}"        @click="select(item)"        :id="`${id}-item-${index}`"        role="option"        :aria-selected="highlightedIndex === index"      >        <slot :item="item">          {{ item[valueKey] }}        </slot>      </li>    </AutocompleteSuggestion>  </div></template><script>import { Autocomplete } from 'element-ui';import AutocompleteSuggestion from './AutocompleteSuggestion.vue';export default {  name: 'LineDescriptionAutocomplete',  extends: Autocomplete,  components: {    AutocompleteSuggestion,  },  methods: {    handleFocus(event) {      this.activated = true;      this.$emit('focus', event);      if (this.triggerOnFocus) {        this.debouncedGetData(this.value);      }      this.dispatch('ElFormItem', 'el.form.input.focus');    },    handleBlur(event) {      this.$emit('blur', event);      this.dispatch('ElFormItem', 'el.form.input.blur');    },  },};</script>

Breakdown of the Code

  • Extending el-autocomplete: Using extends: Autocomplete, we inherit the full functionality of Element UI’s Autocomplete component.
  • Customizing handleFocus method: We override the focus behavior to emit an event and trigger additional functionality.
  • Modifying handleBlur method: We ensure that the blur event dispatches to the parent ElFormItem, ensuring consistent behavior across forms.
  • Keeping all slots & bindings intact: This ensures we don’t break any existing props, slots, or event listeners from Element UI.

Benefits of Using Vue.extend

  1. Reusability: We reuse Element UI’s existing features without rewriting the component.
  2. Maintainability: We only modify the parts we need, making updates easier.
  3. Less Code Duplication: We avoid duplicating logic from the original component.
  4. Full Compatibility: Our extended component remains compatible with Element UI’s updates.

Conclusion

Extending Element UI components using Vue.extend is a powerful way to tweak existing functionality while preserving the framework’s benefits. In this example, we customized el-autocomplete to modify how it handles focus and blur events, demonstrating how flexible Vue 2’s inheritance model is.

If you're working with Element UI and find yourself needing additional features, consider using Vue.extend before resorting to fully custom components—it will save you time and effort while keeping your code clean and maintainable!