Vue MQ: Responsive Design Plugin
Vue MQ is a Vue.js plugin designed to simplify responsive web design by providing a declarative and semantic approach to handling media queries. It integrates directly into Vue instances, exposing a reactive `$mq` property that reflects the current breakpoint. Additionally, it offers a `MqLayout` component for conditional rendering of content based on specified breakpoints, including support for ranges (e.g., `md+`) and multiple specific breakpoints. The current stable version is 1.0.1, with significant updates like Server-Side Rendering (SSR) support introduced in v1.0.0. Releases appear to be infrequent, focusing on stability and key features. A core differentiator is its mobile-first design philosophy, particularly evident in its filter utility, allowing developers to define breakpoints centrally and manage responsive behavior directly within Vue templates and component logic, rather than relying solely on CSS media queries. This abstraction aims to streamline the development of responsive user interfaces.
Common errors
-
[Vue warn]: Unknown custom element: <mq-layout> - did you register the component correctly?
cause The `vue-mq` plugin, which globally registers the `MqLayout` component, has not been installed or has not been installed correctly via `Vue.use()`.fixEnsure `import VueMq from 'vue-mq'; Vue.use(VueMq, { breakpoints: {...} });` is executed before your Vue application or components are mounted. -
TypeError: this.$mq is undefined
cause The `$mq` instance property is injected into Vue instances by the `vue-mq` plugin. This error indicates the plugin was not successfully installed or the code attempting to access `$mq` is outside a Vue component context.fixVerify that `Vue.use(VueMq, ...)` is called once and correctly at your application's entry point. Ensure `$mq` is only accessed within Vue component instances (e.g., in `template`, `computed`, `methods`). -
Responsive behavior does not update or screen size changes are not detected in older browsers.
cause The browser environment (e.g., Internet Explorer, older versions of Chrome/Firefox) lacks native support for the `window.matchMedia` API, which `vue-mq` uses to detect breakpoint changes.fixIntegrate a `matchMedia` polyfill into your project to provide the necessary API for older browsers. Common polyfills are available on GitHub.
Warnings
- breaking This `vue-mq` package is exclusively for Vue 2 applications. It is not compatible with Vue 3. For Vue 3 projects, you must use the `vue3-mq` package, which has a distinct API and installation method.
- gotcha Older browsers and Internet Explorer do not natively support the `matchMedia` API, which `vue-mq` relies on for responsive functionality. Without a polyfill, responsive features will not work as expected in these environments.
- gotcha The `$mq | mq` filter operates with a mobile-first philosophy. If values are omitted for intermediate breakpoints, the filter will fall back to the value defined for the next smallest breakpoint. This can lead to unexpected behavior if not understood.
Install
-
npm install vue-mq -
yarn add vue-mq -
pnpm add vue-mq
Imports
- VueMq
import { VueMq } from 'vue-mq'import VueMq from 'vue-mq'
Quickstart
import Vue from 'vue';
import VueMq from 'vue-mq';
// Create a root element for the Vue application in a browser environment
const appElement = document.createElement('div');
appElement.id = 'app';
document.body.appendChild(appElement);
// Install the Vue MQ plugin with custom breakpoints
Vue.use(VueMq, {
breakpoints: { // Define custom, named breakpoints
xs: 0,
sm: 450,
md: 800,
lg: 1250,
xl: Infinity
},
defaultBreakpoint: 'sm' // Customize for SSR or initial state
});
// Create a new Vue instance to demonstrate reactive behavior
new Vue({
el: '#app',
data: {
appMessage: 'Responsive Demo with Vue MQ'
},
computed: {
// Reactive computed property based on the current breakpoint
displayText() {
return this.$mq === 'sm' ? 'Viewing on a small screen!' : `Current breakpoint: ${this.$mq}`;
}
},
template: `
<div>
<h1>{{ appMessage }}</h1>
<p>{{ displayText }}</p>
<!-- Conditional rendering using MqLayout component -->
<mq-layout mq="sm">
<p>This content is specifically for small screens (sm).</p>
</mq-layout>
<mq-layout mq="md+">
<p>This content displays on medium screens and larger (md, lg, xl).</p>
</mq-layout>
<mq-layout :mq="['lg', 'xl']">
<p>This content shows on large or extra-large screens (lg or xl).</p>
</mq-layout>
<!-- Using the $mq property with the mq filter for dynamic props -->
<div style="border: 1px solid #ccc; padding: 10px; margin-top: 20px;">
<p>Dynamic grid columns via filter: <strong>{{ $mq | mq({ xs: 1, sm: 2, md: 3, lg: 4, xl: 5 }) }}</strong></p>
<p>Resize your browser window to see the breakpoints and content change!</p>
</div>
</div>
`,
});