Package Exports
- vue-case
- vue-case/dist/vue-case.common.js
- vue-case/dist/vue-case.umd.js
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (vue-case) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
๐ค vue-case
Professional Case Transformation Library for Vue 3
Transform strings between 19+ case formats with full TypeScript support
Features โข Installation โข Quick Start โข API Reference โข Examples โข Documentation โข Live Demo
๐ Highlights
โ ๏ธ Version 2.0 - Complete rewrite for Vue 3 with full TypeScript support and 100% test coverage. For Vue 2, use version 1.x.
import { camelCase, pascalCase, snakeCase } from 'vue-case';
camelCase('hello world') // โ 'helloWorld'
pascalCase('hello world') // โ 'HelloWorld'
snakeCase('hello world') // โ 'hello_world'โจ Features
๐ฏ Core Features
|
๐ Vue 3 Integration
|
๐ฆ Installation
|
npm npm install vue-case |
pnpm pnpm add vue-case |
yarn yarn add vue-case |
CDN Usage
<!-- Vue 3 -->
<script src="https://unpkg.com/vue@3"></script>
<!-- vue-case -->
<script src="https://unpkg.com/vue-case@2"></script>
<script>
const { createApp } = Vue;
const app = createApp({
template: '<div>{{ $camelCase("hello world") }}</div>'
});
app.use(VueCase);
app.mount('#app');
</script>๐ Quick Start
๐ต Composition API (Recommended)
<template>
<div class="converter">
<input v-model="text" placeholder="Enter text..." />
<div class="results">
<p>camelCase: <code>{{ camelCase(text) }}</code></p>
<p>PascalCase: <code>{{ pascalCase(text) }}</code></p>
<p>snake_case: <code>{{ snakeCase(text) }}</code></p>
<p>kebab-case: <code>{{ paramCase(text) }}</code></p>
</div>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue';
import { useCase } from 'vue-case';
const { camelCase, pascalCase, snakeCase, paramCase } = useCase();
const text = ref('Hello World');
</script>๐ข Options API
<template>
<div>
<p>{{ $camelCase(username) }}</p>
<p>{{ $snakeCase(username) }}</p>
<p>{{ $truncate(description, 50) }}</p>
</div>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
export default defineComponent({
data() {
return {
username: 'John Doe',
description: 'A very long description text...'
};
}
});
</script>๐ฃ Direct Imports (Tree-Shakeable)
import { camelCase, pascalCase, snakeCase, constantCase } from 'vue-case';
// Use anywhere in your code
const apiEndpoint = camelCase('user profile'); // 'userProfile'
const className = pascalCase('my component'); // 'MyComponent'
const dbColumn = snakeCase('user name'); // 'user_name'
const envVar = constantCase('api key'); // 'API_KEY'๐ Usage Guide
1๏ธโฃ Plugin Installation (Global Access)
Setup in main.ts:
import { createApp } from 'vue';
import VueCase from 'vue-case';
import App from './App.vue';
const app = createApp(App);
// Install plugin globally
app.use(VueCase);
app.mount('#app');Use in any component:
<template>
<div>
<!-- Available as $camelCase, $pascalCase, $snakeCase, etc. -->
<h1>{{ $titleCase(pageTitle) }}</h1>
<p>{{ $truncate(content, 100) }}</p>
</div>
</template>2๏ธโฃ Composition API with useCase()
<script setup lang="ts">
import { useCase } from 'vue-case';
import { ref, computed } from 'vue';
// Get all transformation methods
const { camelCase, pascalCase, snakeCase, constantCase, truncate } = useCase();
const inputText = ref('user profile settings');
// Use in computed properties
const apiRoute = computed(() => camelCase(inputText.value));
const component = computed(() => pascalCase(inputText.value));
const database = computed(() => snakeCase(inputText.value));
const environment = computed(() => constantCase(inputText.value));
</script>
<template>
<div>
<input v-model="inputText" />
<ul>
<li>API: {{ apiRoute }}</li>
<li>Component: {{ component }}</li>
<li>Database: {{ database }}</li>
<li>Environment: {{ environment }}</li>
</ul>
</div>
</template>3๏ธโฃ TypeScript Integration
import type {
CaseMethods,
CaseTransformFn,
CaseCheckFn,
TruncateFn,
VueCaseOptions
} from 'vue-case';
import { camelCase, pascalCase, useCase } from 'vue-case';
// Type-safe function
const transformUserInput: CaseTransformFn = (input: string) => {
return camelCase(input);
};
// Type-safe composable usage
const caseMethods: CaseMethods = useCase();
// Use in classes
class StringTransformer {
private transform: CaseTransformFn;
constructor() {
this.transform = pascalCase;
}
process(input: string): string {
return this.transform(input);
}
}๐จ Available Methods
๐ Complete Transformation Reference
| Method | Input | Output | Use Case |
|---|---|---|---|
camelCase |
'hello world' |
'helloWorld' |
JavaScript variables, object keys |
pascalCase |
'hello world' |
'HelloWorld' |
Component names, class names |
snakeCase |
'hello world' |
'hello_world' |
Database columns, Python variables |
constantCase |
'hello world' |
'HELLO_WORLD' |
Environment variables, constants |
paramCase |
'hello world' |
'hello-world' |
URLs, CSS classes, file names |
dotCase |
'hello world' |
'hello.world' |
Object paths, configuration keys |
pathCase |
'hello world' |
'hello/world' |
File paths, routes |
headerCase |
'hello world' |
'Hello-World' |
HTTP headers |
capitalCase |
'hello world' |
'Hello World' |
Titles, display names |
titleCase |
'hello world' |
'Hello World' |
Book titles, headings |
sentenceCase |
'HELLO WORLD' |
'Hello world' |
Sentences, descriptions |
noCase |
'helloWorld' |
'hello world' |
Remove formatting |
lowerCase |
'HELLO WORLD' |
'hello world' |
Normalize to lowercase |
upperCase |
'hello world' |
'HELLO WORLD' |
Normalize to uppercase |
lowerCaseFirst |
'Hello' |
'hello' |
Lowercase first letter |
upperCaseFirst |
'hello' |
'Hello' |
Capitalize first letter |
swapCase |
'Hello World' |
'hELLO wORLD' |
Toggle case |
๐ ๏ธ Utility Methods
| Method | Signature | Description | Example |
|---|---|---|---|
truncate |
(text: string, length?: number) |
Truncate text with "..." | truncate('Hello World', 5) โ 'Hello...' |
isLowerCase |
(text: string): boolean |
Check if lowercase | isLowerCase('hello') โ true |
isUpperCase |
(text: string): boolean |
Check if uppercase | isUpperCase('HELLO') โ true |
๐ก Real-World Examples
๐น Example 1: API Request/Response Transformer
import { camelCase, snakeCase } from 'vue-case';
// Transform snake_case API responses to camelCase
function transformResponse<T extends Record<string, any>>(data: T): Record<string, any> {
return Object.entries(data).reduce((acc, [key, value]) => {
acc[camelCase(key)] = value;
return acc;
}, {} as Record<string, any>);
}
// Transform camelCase to snake_case for API requests
function transformRequest<T extends Record<string, any>>(data: T): Record<string, any> {
return Object.entries(data).reduce((acc, [key, value]) => {
acc[snakeCase(key)] = value;
return acc;
}, {} as Record<string, any>);
}
// Usage with Axios
import axios from 'axios';
const api = axios.create({
baseURL: 'https://api.example.com',
transformResponse: [(data) => {
const parsed = JSON.parse(data);
return transformResponse(parsed);
}],
transformRequest: [(data) => {
return JSON.stringify(transformRequest(data));
}]
});
// Now your API calls work seamlessly:
const response = await api.get('/user_profile'); // API returns user_name
console.log(response.data.userName); // Access as userName๐น Example 2: Dynamic Component Generator
<template>
<component
:is="getComponent(type)"
:class="getClassName(type)"
>
{{ content }}
</component>
</template>
<script setup lang="ts">
import { computed } from 'vue';
import { pascalCase, paramCase } from 'vue-case';
interface Props {
type: string;
content: string;
}
const props = defineProps<Props>();
// Convert 'user card' โ 'UserCard' for component name
const getComponent = (type: string) => {
return pascalCase(type);
};
// Convert 'user card' โ 'user-card' for CSS class
const getClassName = (type: string) => {
return `component-${paramCase(type)}`;
};
</script>๐น Example 3: Form Field Generator
<template>
<form @submit.prevent="handleSubmit">
<div v-for="field in formFields" :key="field.name">
<label :for="field.id">{{ field.label }}</label>
<input
:id="field.id"
:name="field.name"
v-model="formData[field.name]"
/>
</div>
<button type="submit">Submit</button>
</form>
</template>
<script setup lang="ts">
import { ref, computed } from 'vue';
import { camelCase, paramCase, capitalCase } from 'vue-case';
const fieldNames = ['user name', 'email address', 'phone number'];
const formFields = computed(() =>
fieldNames.map(name => ({
name: camelCase(name), // 'userName' for v-model
id: paramCase(name), // 'user-name' for id/for
label: capitalCase(name) // 'User Name' for display
}))
);
const formData = ref(
fieldNames.reduce((acc, name) => {
acc[camelCase(name)] = '';
return acc;
}, {} as Record<string, string>)
);
const handleSubmit = () => {
console.log(formData.value);
// { userName: '...', emailAddress: '...', phoneNumber: '...' }
};
</script>๐น Example 4: URL Slug Generator
<template>
<div class="blog-editor">
<input
v-model="title"
placeholder="Blog post title"
@input="generateSlug"
/>
<p class="slug-preview">
URL: <code>{{ baseUrl }}/{{ slug }}</code>
</p>
<button @click="copySlug">Copy URL</button>
</div>
</template>
<script setup lang="ts">
import { ref, computed } from 'vue';
import { paramCase } from 'vue-case';
const title = ref('');
const baseUrl = 'https://myblog.com/posts';
const slug = computed(() => paramCase(title.value));
const generateSlug = () => {
// Automatically updates via computed property
};
const copySlug = async () => {
await navigator.clipboard.writeText(`${baseUrl}/${slug.value}`);
alert('URL copied!');
};
</script>๐น Example 5: Environment Variable Manager
import { constantCase, camelCase } from 'vue-case';
class EnvironmentConfig {
private config: Record<string, string> = {};
// Load from process.env
loadFromEnv() {
this.config = {
[camelCase('API_KEY')]: process.env.API_KEY || '',
[camelCase('DATABASE_URL')]: process.env.DATABASE_URL || '',
[camelCase('APP_NAME')]: process.env.APP_NAME || '',
};
return this.config;
}
// Generate .env content
generateEnvFile(config: Record<string, string>): string {
return Object.entries(config)
.map(([key, value]) => `${constantCase(key)}=${value}`)
.join('\n');
}
}
// Usage
const env = new EnvironmentConfig();
const config = {
apiKey: 'secret123',
databaseUrl: 'postgresql://...',
appName: 'My App'
};
console.log(env.generateEnvFile(config));
// Output:
// API_KEY=secret123
// DATABASE_URL=postgresql://...
// APP_NAME=My App๐น Example 6: CSS Class Generator
<template>
<div :class="bem('container')">
<div :class="bem('header')">
<h1 :class="bem('title', 'large')">{{ title }}</h1>
</div>
<div :class="bem('content', isActive && 'active')">
<slot />
</div>
</div>
</template>
<script setup lang="ts">
import { paramCase } from 'vue-case';
import { ref } from 'vue';
const componentName = 'UserProfile';
const blockName = paramCase(componentName); // 'user-profile'
// BEM (Block Element Modifier) helper
const bem = (element: string, modifier?: string | boolean) => {
const base = `${blockName}__${paramCase(element)}`;
if (modifier && typeof modifier === 'string') {
return `${base} ${base}--${paramCase(modifier)}`;
}
return base;
};
const title = ref('User Profile');
const isActive = ref(true);
// Generates classes like:
// user-profile__container
// user-profile__header
// user-profile__title user-profile__title--large
// user-profile__content user-profile__content--active
</script>๐น Example 7: Database Query Builder
import { snakeCase } from 'vue-case';
interface QueryFilters {
[key: string]: any;
}
class QueryBuilder {
private tableName: string;
private filters: Record<string, any> = {};
constructor(tableName: string) {
this.tableName = snakeCase(tableName);
}
where(filters: QueryFilters) {
this.filters = Object.entries(filters).reduce((acc, [key, value]) => {
acc[snakeCase(key)] = value;
return acc;
}, {} as Record<string, any>);
return this;
}
build(): string {
const conditions = Object.entries(this.filters)
.map(([key, value]) => `${key} = '${value}'`)
.join(' AND ');
return `SELECT * FROM ${this.tableName} WHERE ${conditions}`;
}
}
// Usage
const query = new QueryBuilder('UserProfile')
.where({
firstName: 'John',
emailAddress: 'john@example.com'
})
.build();
console.log(query);
// SELECT * FROM user_profile WHERE first_name = 'John' AND email_address = 'john@example.com'๐น Example 8: Internationalization Key Generator
import { dotCase } from 'vue-case';
interface TranslationKeys {
[key: string]: string | TranslationKeys;
}
function generateI18nKeys(prefix: string, keys: string[]): TranslationKeys {
return keys.reduce((acc, key) => {
const i18nKey = dotCase(`${prefix} ${key}`);
acc[i18nKey] = `${prefix}.${key}`;
return acc;
}, {} as TranslationKeys);
}
// Generate translation keys
const userKeys = generateI18nKeys('user', [
'profile settings',
'account details',
'privacy settings'
]);
console.log(userKeys);
// {
// 'user.profile.settings': 'user.profile settings',
// 'user.account.details': 'user.account details',
// 'user.privacy.settings': 'user.privacy settings'
// }
// Use in Vue components
import { useI18n } from 'vue-i18n';
const { t } = useI18n();
const title = t(userKeys['user.profile.settings']);๐งช Testing
Full support for all major testing frameworks:
import { describe, it, expect } from 'vitest'; // or jest
import { camelCase, pascalCase, snakeCase } from 'vue-case';
describe('vue-case transformations', () => {
it('transforms to camelCase', () => {
expect(camelCase('hello world')).toBe('helloWorld');
expect(camelCase('hello-world')).toBe('helloWorld');
expect(camelCase('hello_world')).toBe('helloWorld');
});
it('transforms to PascalCase', () => {
expect(pascalCase('hello world')).toBe('HelloWorld');
});
it('handles edge cases', () => {
expect(camelCase('')).toBe('');
expect(camelCase('a')).toBe('a');
expect(camelCase('hello@world')).toBe('helloWorld');
});
});๐ Performance
- โก Minimal Bundle Size: ~22KB minified
- ๐ Tree Shakeable: Import only what you need
- ๐ฏ Zero Dependencies: Built on lightweight
text-caselibrary - ๐จ Fast Execution: Optimized for performance
- ๐ฆ Efficient: No runtime overhead
๐ Browser Support
![]() |
![]() |
![]() |
![]() |
|---|---|---|---|
| Latest โ | Latest โ | Latest โ | Latest โ |
๐ง Advanced Configuration
Custom Plugin Options
import { createApp } from 'vue';
import VueCase from 'vue-case';
import type { VueCaseOptions } from 'vue-case';
const app = createApp(App);
// Custom options (currently all methods are included by default)
const options: VueCaseOptions = {
// Future: Configure which methods to include
};
app.use(VueCase, options);Method Chaining
import { camelCase, upperCaseFirst, lowerCase } from 'vue-case';
// Create custom transformations
const customTransform = (text: string) => {
return upperCaseFirst(camelCase(lowerCase(text)));
};
customTransform('HELLO WORLD'); // 'HelloWorld'๐ Type Definitions
// All available types exported
export type CaseTransformFn = (value: string) => string;
export type TruncateFn = (value: string, length?: number) => string;
export type CaseCheckFn = (value: string) => boolean;
export interface CaseMethods {
camelCase: CaseTransformFn;
pascalCase: CaseTransformFn;
capitalCase: CaseTransformFn;
headerCase: CaseTransformFn;
titleCase: CaseTransformFn;
pathCase: CaseTransformFn;
paramCase: CaseTransformFn;
dotCase: CaseTransformFn;
snakeCase: CaseTransformFn;
constantCase: CaseTransformFn;
lowerCase: CaseTransformFn;
lowerCaseFirst: CaseTransformFn;
upperCase: CaseTransformFn;
upperCaseFirst: CaseTransformFn;
swapCase: CaseTransformFn;
sentenceCase: CaseTransformFn;
noCase: CaseTransformFn;
isLowerCase: CaseCheckFn;
isUpperCase: CaseCheckFn;
truncate: TruncateFn;
}
export interface VueCaseOptions {
// Plugin configuration options
}
// Global property types for Options API
declare module 'vue' {
interface ComponentCustomProperties {
$case: CaseMethods;
$camelCase: CaseTransformFn;
$pascalCase: CaseTransformFn;
// ... all other methods
}
}โ FAQ
Q: Can I use this with Vue 2?
A: No, version 2.0+ is for Vue 3 only. For Vue 2, use version 1.x:
npm install vue-case@1Q: Does this work with Nuxt 3?
A: Yes! Just install and use it like any other Vue 3 plugin:
// plugins/vue-case.ts
import VueCase from 'vue-case';
export default defineNuxtPlugin((nuxtApp) => {
nuxtApp.vueApp.use(VueCase);
});Q: Can I use this without Vue?
A: Yes! Use direct imports:
import { camelCase, snakeCase } from 'vue-case';
// Works in any JavaScript/TypeScript projectQ: Is this tree-shakeable?
A: Yes! When you use direct imports, only the methods you import will be included in your bundle.
Q: What's the difference between paramCase and kebab-case?
A: They're the same! paramCase produces kebab-case format (hello-world).
๐ค Contributing
We welcome contributions! Here's how you can help:
- ๐ด Fork the repository
- ๐ง Create your feature branch (
git checkout -b feature/AmazingFeature) - โ
Test your changes (
pnpm test) - ๐พ Commit your changes (
git commit -m 'Add some AmazingFeature') - ๐ค Push to the branch (
git push origin feature/AmazingFeature) - ๐ Open a Pull Request
Development Setup
# Clone the repository
git clone https://github.com/idimetrix/vue-case.git
cd vue-case
# Install dependencies
pnpm install
# Run tests
pnpm test
# Run tests with coverage
pnpm test --coverage
# Build library
pnpm run build
# Type check
pnpm run typecheck
# Run dev server
pnpm serve๐ Changelog
See CHANGELOG.md for detailed release notes.
๐ License
๐ Links
๐ฆ Package |
๐ป Repository |
๐ Issues |
๐ก Discussions |
๐ Support the Project
If you find vue-case helpful, please consider:
- โญ Star the repository on GitHub
- ๐ Report any bugs you find
- ๐ Contribute to documentation
- ๐ก Suggest new features
- ๐ข Share with the community
- ๐ Sponsor the development
๐ Credits
Built with โค๏ธ using:
- Vue 3 - The Progressive JavaScript Framework
- TypeScript - JavaScript with syntax for types
- text-case - Text transformation utilities
๐ Stats
Made with โค๏ธ for the Vue.js community



