Skip to content

Filter

A flexible Vue 3 component for rendering filters in two layouts:

  • inline (horizontal, suitable for toolbars)
  • vertical (scrollable sidebar-style)

It supports two ways to define filters:

  • Schema-based configuration (schema prop)
  • Custom slot content <filter-field>
vue
<filter :schema="schema" :value="{}"></filter>

{ "media": [ "is_photo" ] }

js
// to str
Object.entries(filter).map(([key, val]) => `${key}=${val}`).join('|')
// or
Object.entries(filter).map(el => el.join('=')).join('|')

//str to object 
filterStr.split('|').map(el=>el.split('=')).reduce((f,[k,v])=>Object.assign(f,{[k]:v}),{})

media=is_photo

{ "media": "is_photo" }

Features

  • Supports checkbox, radio, text, and custom filter components.
  • Emits change and clear events when filters are updated or removed.
  • Maintains internal activeFilter state.
  • Automatically adapts layout depending on type.

Component API

NameTypeDefaultDescription
schemaSchema (optional)-Declarative object describing fields and options
viewinline vertical popoverinlineLayout mode for rendering filters

Usage

Schema (Declarative)

vue
<Filters :schema="filterSchema" @change="onChange" @clear="onClear" />
ts
const filterSchema = {
  status: {
    type: 'checkbox',
    label: 'Status',
    options: [
      { id: 'active', text: 'Active' },
      { id: 'inactive', text: 'Inactive' }
    ]
  },
  media: {
    type: 'radio',
    label: 'Media',
    options: [
      { id: 'photo', text: 'Photo' },
      { id: 'video', text: 'Video' }
    ]
  }
};

Slot Components

vue
<filters view="inline" @change="onChange" @clear="onClear">
  <filter-field
    name="category"
    type="checkbox"
    label="Category"
    :options="categoryOptions"
  />
  <filter-field
    name="search"
    type="text"
    label="Search"
  />
</filters>
  • Dynamically renders <filter-field> from schema.
  • Slot components must emit change and clear events with { name, value }.