Vue Horizontal Layout Component
Vue Horizontal is a dedicated Vue.js component designed to simplify the creation of horizontal, scrollable layouts for modern responsive web applications. It offers a pure Vue-native solution, avoiding direct DOM manipulation or external legacy JavaScript libraries, requiring only Vue as a peer dependency. The library explicitly supports all rendering modes including Single Page Applications (SPA), Server-Side Rendering (SSR), and Static Site Generation (SSG), with comprehensive end-to-end testing. Currently stable at version 0.8.13, it primarily supports Vue 2, while a Vue 3 compatible version is available under the `@next` tag. The project maintains an active release cadence, with frequent bug fixes and maintenance updates. Key differentiators include its lightweight footprint (approximately 3 KB on CDN), mobile-first design philosophy, customizable navigation options, and high extensibility, granting developers full control over HTML structure, CSS styling, and interaction logic to achieve desired UX patterns like smooth scrolling and snapping.
Common errors
-
[Vue warn]: Failed to resolve component: vue-horizontal
cause The `VueHorizontal` component was not properly registered with Vue, either globally or locally within the component where it's being used.fixEnsure `import VueHorizontal from 'vue-horizontal';` is present and the component is added to `components: { VueHorizontal }` in your Vue component or globally via `Vue.component('VueHorizontal', VueHorizontal);`. -
TypeError: Cannot read properties of null (reading '$refs')
cause This error often occurs in SSR environments or when attempting to access a `$ref` before the component has been mounted and the DOM element is available.fixGuard `$refs` access with `if (this.$refs.container)` or defer DOM-dependent logic to `mounted()` lifecycle hook or `this.$nextTick()` callback. -
SyntaxError: Unexpected token 'export' (for require('vue-horizontal'))cause Attempting to import the ESM-only `vue-horizontal` package using CommonJS `require()` syntax in an environment that expects ESM modules.fixUse ESM `import` statements: `import VueHorizontal from 'vue-horizontal';`. Ensure your build setup (Webpack, Rollup, Vite) is configured to handle ESM correctly.
Warnings
- breaking Vue 3 compatibility requires installing the `@next` version of the package. The main `vue-horizontal` package currently targets Vue 2.
- gotcha When using Server-Side Rendering (SSR), ensure that DOM-dependent operations (like accessing `$refs.container` children) are properly guarded or performed only client-side to prevent errors during the server build process.
- gotcha Careful consideration of CSS styling is required, especially for the last child element within the horizontal layout. Previous versions had specific fixes related to margins on the last child that could cause layout inconsistencies.
- gotcha The `refresh` callback was previously mandatory but has been made optional. If you're using an older version or encountering issues with `refresh`, ensure your implementation aligns with the expected API.
Install
-
npm install vue-horizontal -
yarn add vue-horizontal -
pnpm add vue-horizontal
Imports
- VueHorizontal
const VueHorizontal = require('vue-horizontal');import VueHorizontal from "vue-horizontal";
- VueHorizontal (Global)
import Vue from 'vue'; import VueHorizontal from 'vue-horizontal'; Vue.component(VueHorizontal);
import Vue from 'vue'; import VueHorizontal from 'vue-horizontal'; Vue.component('VueHorizontal', VueHorizontal); - Type (Props)
import type { VueHorizontalProps } from 'vue-horizontal';
Quickstart
<template>
<vue-horizontal responsive>
<section v-for="item in items" :key="item.title">
<h3>{{ item.title }}</h3>
<p>{{ item.content }}</p>
</section>
</vue-horizontal>
</template>
<script>
import VueHorizontal from "vue-horizontal";
export default {
components: {VueHorizontal},
data() {
return {
items: [...Array(20).keys()].map((i) => {
return {title: `Item ${i}`, content: `🚀 Content ${i}`};
}),
}
}
}
</script>
<style scoped>
section {
padding: 16px 24px;
background: #f5f5f5;
}
</style>