How the ResizeHandler Mixin Implements Responsive Layout Breakpoints in vue-element-admin
The ResizeHandler mixin provides a debounced, self-contained resize listener that automatically triggers chart redraws when the browser window changes or the admin sidebar collapses, enabling responsive layouts without duplicating boilerplate code.
The vue-element-admin dashboard relies on data visualization components that must adapt to varying screen sizes and layout states. The ResizeHandler mixin, located primarily at src/components/Charts/mixins/resize.js (with an identical copy in src/views/dashboard/admin/components/mixins/resize.js), solves this by encapsulating resize detection logic into a reusable Vue mixin.
Purpose of the ResizeHandler Mixin
The mixin serves as a centralized utility that gives any chart component a self-contained, debounced resize listener. It detects four specific triggers that affect layout dimensions:
- Browser window resize – Detected via the native
windowresizeevent - Sidebar collapse/expand – Detected via the
transitionendevent on the.sidebar-containerelement - Component re-activation – Handled through Vue’s
activatedhook for<keep-alive>scenarios - Cleanup – Managed via
beforeDestroyanddeactivatedhooks to prevent memory leaks
By responding to both window resize and sidebar transition events, the mixin indirectly supports responsive layout breakpoints. When the screen width crosses a breakpoint (e.g., the sidebar collapses at 768 px), the transitionend event fires, causing the chart to re-measure its container and redraw at the correct size.
Core Implementation Details
The mixin uses private property naming conventions ($_…) to avoid polluting the component’s public API, following Vue’s style guide.
Debounced Window Resize Detection
The mixin initializes a debounced handler that waits 100 ms after the last resize event before executing. This prevents performance issues during rapid resizing operations, such as when a user drags the browser window corner.
// src/components/Charts/mixins/resize.js
import { debounce } from '@/utils' // located in src/utils/index.js
export default {
data() {
return {
$_sidebarElm: null,
$_resizeHandler: null
}
},
mounted() {
this.initListener()
},
methods: {
initListener() {
this.$_resizeHandler = debounce(() => { this.resize() }, 100)
window.addEventListener('resize', this.$_resizeHandler)
// Sidebar handling...
},
resize() {
const { chart } = this
chart && chart.resize()
}
}
}
Sidebar Transition Handling
To detect sidebar collapse (which affects available chart width), the mixin attaches a transitionend listener to the DOM element with the class sidebar-container. It filters for width property changes specifically to avoid triggering on other CSS transitions.
// Inside initListener()
this.$_sidebarElm = document.getElementsByClassName('sidebar-container')[0]
this.$_sidebarElm && this.$_sidebarElm.addEventListener(
'transitionend', this.$_sidebarResizeHandler)
// Handler method
$_sidebarResizeHandler(e) {
if (e.propertyName === 'width') {
this.$_resizeHandler()
}
}
Keep-Alive Lifecycle Support
For components wrapped in <keep-alive>, the mixin re-initializes listeners when the component is activated and forces an immediate resize to ensure the chart fits the current container dimensions.
activated() {
if (!this.$_resizeHandler) {
this.initListener()
}
this.resize()
},
deactivated() {
this.destroyListener()
},
beforeDestroy() {
this.destroyListener()
}
Integrating the Mixin in Chart Components
Basic Component Setup
Any chart component can import the mixin to gain automatic resize capabilities. The component must expose a chart property (typically an ECharts instance) that the mixin’s resize() method can call.
<!-- src/components/Charts/MixChart.vue -->
<template>
<div ref="chart" class="chart-container" />
</template>
<script>
import resize from './mixins/resize'
export default {
name: 'MixChart',
mixins: [resize],
mounted() {
// Initialize ECharts and store reference
this.chart = echarts.init(this.$refs.chart)
this.chart.setOption(this.chartOptions)
},
props: {
chartOptions: Object
}
}
</script>
Responsive Grid Implementation
When placed inside Element UI’s responsive grid system, charts automatically adapt to breakpoint changes. The mixin ensures that when the sidebar collapses at the 992 px breakpoint (or when columns shift at xs/sm/md breakpoints), the chart receives a resize event.
<template>
<el-row :gutter="20">
<el-col :xs="24" :sm="12" :md="8">
<mix-chart :chart-options="pieOptions" />
</el-col>
<el-col :xs="24" :sm="12" :md="8">
<mix-chart :chart-options="lineOptions" />
</el-col>
</el-row>
</template>
<script>
import MixChart from '@/components/Charts/MixChart'
export default {
components: { MixChart },
data() {
return {
pieOptions: { /* ... */ },
lineOptions: { /* ... */ }
}
}
}
</script>
Key Files in the Architecture
| File | Role |
|---|---|
src/components/Charts/mixins/resize.js |
Core mixin implementation providing debounced resize logic and sidebar detection. |
src/views/dashboard/admin/components/mixins/resize.js |
Identical duplicate used by dashboard-specific chart views. |
src/components/Charts/MixChart.vue |
Example chart component consuming the mixin for ECharts integration. |
src/views/dashboard/admin/components/LineChart.vue |
Real-world line chart implementation using the mixin. |
src/views/dashboard/admin/components/BarChart.vue |
Bar chart component utilizing the resize functionality. |
src/views/dashboard/admin/components/PieChart.vue |
Pie chart component with automatic resize support. |
src/utils/index.js |
Contains the debounce utility function imported by the mixin. |
Summary
- The ResizeHandler mixin centralizes resize logic for chart components in vue-element-admin, eliminating duplicate boilerplate across the codebase.
- It implements a 100ms debounced handler to optimize performance during rapid resize operations.
- The mixin detects both window resize and sidebar transitionend events, enabling charts to respond to responsive layout breakpoints automatically.
- It provides full keep-alive lifecycle support through
activatedanddeactivatedhooks, preventing memory leaks and ensuring correct sizing when cached components re-activate. - Located in
src/components/Charts/mixins/resize.js, the mixin is consumed by dashboard components includingMixChart.vue,LineChart.vue, andBarChart.vue.
Frequently Asked Questions
What is the purpose of the ResizeHandler mixin in vue-element-admin?
The ResizeHandler mixin provides a reusable, self-contained resize listener that automatically triggers chart redraws when the browser window changes size or the admin sidebar collapses. It eliminates the need to duplicate resize detection logic across multiple chart components, ensuring consistent responsive behavior throughout the dashboard.
How does the ResizeHandler mixin detect sidebar collapse events?
The mixin attaches a transitionend event listener to the DOM element with the class sidebar-container. When the sidebar's CSS width transition completes, the $_sidebarResizeHandler method checks if e.propertyName === 'width' to filter out unrelated transitions, then triggers the debounced resize handler to redraw the chart.
Why does the ResizeHandler mixin use a 100ms debounce for resize events?
The 100ms debounce, implemented using the utility from src/utils/index.js, prevents performance degradation during rapid resize operations such as dragging the browser window corner or animating the sidebar. This ensures the chart library (ECharts) only recalculates dimensions after the resizing activity stabilizes, avoiding unnecessary redraws.
How does the ResizeHandler mixin support Vue's keep-alive feature?
The mixin implements the activated hook to re-initialize resize listeners if they were destroyed while the component was cached, and forces an immediate resize() call so the chart fits the current container dimensions. The deactivated hook removes the listeners to prevent memory leaks while the component remains in the keep-alive cache.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →