Frontend Development 13 min read

Design and Implementation of a BI Filter Component Library (bi-filters)

The article details how the BI platform’s bulky, tightly‑coupled filter was refactored into a standalone, generic ‘bi‑filters’ library managed with Lerna and Vue‑CLI, enabling on‑demand imports, independent packaging, and a three‑layer design that improves extensibility, universality, robustness, reduces code size, and simplifies maintenance.

vivo Internet Technology
vivo Internet Technology
vivo Internet Technology
Design and Implementation of a BI Filter Component Library (bi-filters)

This article is the second part of the "BI Data Visualization Platform Construction" series, focusing on the filter component.

The filter component is a core part of the BI platform, responsible for quickly locating required information and extracting useful data from massive datasets for analysis and decision‑making. As the platform grew, the original filter architecture became bulky and hard to maintain, prompting a complete architectural upgrade.

1. Preliminary Design

The early filter component performed simple one‑way data filtering for charts and was implemented as a business component.

2. Component Classification

Components are divided into two categories: business components and generic components. Both share three essential qualities: extensibility, universality, and robustness.

Extensibility : can be re‑packaged and extended following the open‑closed principle. Universality : measured by how well the component can be decoupled from specific business logic. Robustness : defensive coding, boundary checks, and unit tests to avoid crashes.

The two types are not mutually exclusive; the choice depends on business scenarios and requirements.

3. Pain Points of the Legacy Filter

The old filter suffered from high maintenance cost and numerous bugs due to:

Duplicate code and low reusability.

High business coupling without proper design patterns.

Inconsistent coding style (mixed Vue and React JSX).

Deep component nesting and bidirectional data flow, violating Vue’s one‑way data flow.

4. New Architecture Design

The new design treats the filter as a generic component , extracting it from the BI business code and moving it into a dedicated library called bi-filters . The library is built with Vue CLI and managed by Lerna, enabling independent packaging, on‑demand loading, and simple configuration.

5. Implementation Details

The library follows a multi‑package structure managed by Lerna. Each filter component is an independent npm package, supporting on‑demand import and isolated deployment.

Key features of the library:

On‑demand import : each UI component is a separate npm package.

Simplified configuration : each package can have its own build config; Vue CLI can build UI components with zero webpack configuration.

Independent deployment : version iteration is faster because components are released individually.

Example of using Lerna for multi‑package management:

Directory structure of the component library (illustrated with screenshots).

Component Design and Implementation

The filter components are designed using the decorator pattern to separate business state from UI state. Each component is split into container, logic, and presentation layers.

Example: TextDropDownFilter component.

Code snippets (kept intact):

<!-- page.vue -->
<TextDropDownFilter>
  <template #addonSearchAfter>
    <!-- Business scenario 1 -->
    <a-tooltip v-if="xxx">
      <BIIcon type="icon-jilian" class="btn-jilian" v-show="xxx"></BIIcon>
    </a-tooltip>
    <!-- Business scenario 2 -->
    <a-tooltip v-if="xxx">
      <AIcon type="warning" theme="filled" class="btn-warning"></AIcon>
    </a-tooltip>
  </template>
</TextDropDownFilter>
<!-- SearchHandler.vue -->
<template>
  <div class="bd-search" :class="{ 'active': inputActive }">
    <!-- Base search component -->
    <Search v-bind="$attrs" :searchValue="searchValue" :placeholder="placeholder"
            @searchItem="handleSearchItem" @pressEnter="handlePressEnter"
            @focus="handleFocus" @blur="handleBlur"></Search>
    <slot name="addonSearchAfter"></slot>
  </div>
</template>
<!-- Search.vue -->
<template>
  <AInput class="common-search-input" :placeholder="placeholder" :value="searchValue" allow-clear
          @change="change" v-on="$listeners" @pressEnter="$emit('pressEnter', $event)">
    <AIcon slot="prefix" type="search" />
  </AInput>
</template>

The library uses Vue CLI’s build‑library mode with the --target lib option to generate UMD bundles for each filter component.

Each component package includes a package.json defining its name, version, entry file, and build scripts.

{
  "name": "@bigdata/TextDropDownFilter",
  "version": "0.0.0",
  "private": false,
  "main": "dist/ComponentName.umd.min.js",
  "scripts": {
    "build": "vue-cli-service build --target lib --name ComponentName --dest dist ./index.js"
  },
  "files": ["dist"],
  "license": "ISC"
}

6. Benefits

1) Overall code size of the BI project is reduced, and the component directory becomes clearer, allowing developers to focus on business logic.

2) After extracting the filter logic, the component can be maintained and iterated independently, reducing coupling and improving stability and performance.

7. Conclusion

The component abstraction granularity has no universal standard; it should adapt to varying business scenarios. A well‑designed component library, while neutral in methodology, must align with industry‑specific requirements and product integration considerations to ensure extensibility and maintainability.

frontendVuelibraryComponent DesignBIFilter
vivo Internet Technology
Written by

vivo Internet Technology

Sharing practical vivo Internet technology insights and salon events, plus the latest industry news and hot conferences.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.