Vue Snip
vue-snip is a Vue.js directive designed for clamping the content of text elements when they exceed a specified number of lines. It offers two primary snipping approaches: CSS-based (for performance) and JavaScript-based (for greater accuracy and control), selectable on a per-element basis to optimize for different scenarios. A key feature is its ability to automatically re-snip content when the element's size changes (e.g., due to window resize) or when reactive data influencing the text content updates, eliminating the need for manual recalculations. The library intelligently determines line heights without requiring explicit specification from the developer. Under the hood, vue-snip leverages the `js-snip` library for its core snipping logic. The current stable version is 2.0.2, and it supports both Vue 2 and Vue 3 environments through distinct installation patterns. While there isn't a stated strict release cadence, updates tend to align with Vue ecosystem changes or enhancements to the underlying snipping logic, focusing on stability and performance for text truncation needs.
Common errors
-
TypeError: Cannot read properties of undefined (reading 'use') at <Root>
cause Attempting to use `Vue.use()` in a Vue 3 environment where `Vue` is not globally exposed or when using the Composition API setup.fixFor Vue 3, ensure you use `createApp(App).use(VueSnip).mount('#app')` instead of `Vue.use(VueSnip)`. -
[Vue warn]: Failed to resolve directive: snip
cause The `vue-snip` plugin has not been correctly installed or registered with your Vue application instance.fixEnsure you have called `Vue.use(VueSnip)` (Vue 2) or `createApp(...).use(VueSnip)` (Vue 3) before mounting your application. -
Property 'onSnipped' does not exist on type '{ ... }' (for Vue 3 Composition API)cause The `onSnipped` callback is defined in the `methods` option (Vue 2 Options API) or directly returned from `setup()` (Vue 3 Composition API), but not correctly bound to the `v-snip` directive.fixEnsure your `onSnipped` method is correctly returned from `setup()` in Vue 3 or part of the `methods` object in Vue 2, and then referenced in the directive options: `<p v-snip="{ lines: 3, onSnipped }">...</p>`.
Warnings
- breaking Vue 2 and Vue 3 have different plugin installation APIs. Ensure you use `Vue.use(VueSnip)` for Vue 2 projects and `createApp(...).use(VueSnip)` for Vue 3 projects.
- gotcha When using `mode: 'css'`, snipping might not work consistently across all browsers or in specific layout scenarios (e.g., flex containers without explicit widths). JavaScript mode (`mode: 'js'`) offers more robust and consistent behavior but can be slightly less performant.
- gotcha The `v-snip` directive does not have a default `lines` value. If omitted, the directive will not perform any truncation.
Install
-
npm install vue-snip -
yarn add vue-snip -
pnpm add vue-snip
Imports
- VueSnip (Vue 3 plugin)
import { VueSnip } from 'vue-snip'; // Incorrect named import const VueSnip = require('vue-snip'); // CJS not typical for Vue 3import VueSnip from 'vue-snip'; createApp(App).use(VueSnip).mount('#app'); - VueSnip (Vue 2 plugin)
import { VueSnip } from 'vue-snip'; // Incorrect named import createApp(App).use(VueSnip); // Vue 3 syntax on Vue 2import VueSnip from 'vue-snip'; Vue.use(VueSnip);
- v-snip (Directive usage)
<p snip="{ lines: 3 }">...</p> <!-- Not a standard HTML attribute --> <p :v-snip="{ lines: 3 }">...</p> <!-- Colon is for binding, not for directives --><p v-snip="{ lines: 3, mode: 'js' }">...</p>
Quickstart
import { createApp, ref } from 'vue';
import VueSnip from 'vue-snip';
const App = {
template: `
<div id="app">
<h1>Vue Snip Example</h1>
<p v-snip="{ lines: 3, mode: 'js', midWord: false, onSnipped }" :title="currentContent">
{{ currentContent }}
</p>
<p>Has ellipsis: {{ hasEllipsis }}</p>
<button @click="toggleContent">Toggle Content Length</button>
<p v-snip="{ lines: 2, mode: 'css' }">
This is another paragraph demonstrating CSS mode snipping. It prioritizes
browser performance but might have varying compatibility. This example
will limit the text to two lines using CSS truncation. It's often a good
choice for static content or when maximum performance is critical.
</p>
</div>
`,
setup() {
const hasEllipsis = ref(false);
const fullContent = `This is a very long paragraph that demonstrates the functionality of vue-snip. It will be truncated to a maximum of three lines. If the content exceeds these three lines, an ellipsis will be added to indicate that more text is available. The 'onSnipped' callback will be triggered when the snipping occurs or changes, allowing us to react to the state of the ellipsis. This example uses JavaScript mode for snipping and ensures that words are not cut in half, making the text more readable. The content might change dynamically, and vue-snip should handle re-snipping automatically.`;
const shortContent = `This is a short paragraph.`;
const currentContent = ref(fullContent);
const onSnipped = (newState: { hasEllipsis: boolean }) => {
hasEllipsis.value = newState.hasEllipsis;
console.log('Snipped state changed:', newState.hasEllipsis);
};
const toggleContent = () => {
currentContent.value = currentContent.value === fullContent ? shortContent : fullContent;
};
return {
hasEllipsis,
onSnipped,
toggleContent,
currentContent,
};
},
};
createApp(App).use(VueSnip).mount('#app');