CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-unplugin-vue-macros

Explore more macros and syntax sugar to Vue.

Pending
Overview
Eval results
Files

syntax-sugar.mddocs/

Syntax Sugar

Shorthand syntax and convenience features for Vue templates and scripts.

Capabilities

Short Emits

Shorthand syntax for emitting events.

/**
 * Short emit function with simplified syntax
 * @param name - Event name from defined emits
 * @param args - Event arguments
 */
declare function emits<T extends Record<string, any>>(
  name: keyof T, 
  ...args: any[]
): void;

// Configuration options
interface OptionsShortEmits extends BaseOptions {
  /** Enable short emits syntax */
  enabled?: boolean;
}

Usage Examples:

<script setup>
// Define emits normally
const emit = defineEmits<{
  update: [value: string];
  change: [oldValue: string, newValue: string];
  delete: [];
  select: [item: { id: number; name: string }];
}>();

// Short emit syntax (alternative to emit())
function handleUpdate(value: string) {
  emits('update', value);     // Same as: emit('update', value)
}

function handleChange(old: string, newVal: string) {
  emits('change', old, newVal); // Same as: emit('change', old, newVal)
}

function handleDelete() {
  emits('delete');            // Same as: emit('delete')
}
</script>

Short V-Model

Shorthand syntax for v-model bindings.

/**
 * Short v-model syntax using :: prefix
 */
// Template syntax: ::modelValue instead of v-model:modelValue
// Template syntax: ::checked instead of v-model:checked

// Configuration options
interface OptionsShortVmodel extends BaseOptions {
  /** Enable short v-model syntax */
  enabled?: boolean;
}

Usage Examples:

<template>
  <!-- Standard v-model -->
  <input v-model="message" />
  <input v-model:checked="isChecked" />
  
  <!-- Short v-model syntax -->
  <input ::message />         <!-- Same as v-model="message" -->
  <input ::checked />         <!-- Same as v-model:checked="checked" -->
  
  <!-- Works with components -->
  <CustomInput ::value />     <!-- Same as v-model:value="value" -->
  <Modal ::visible />         <!-- Same as v-model:visible="visible" -->
</template>

<script setup>
const message = ref('');
const isChecked = ref(false);
const value = ref('');
const visible = ref(false);
</script>

Short Bind

Shorthand syntax for prop binding.

/**
 * Short bind syntax using : prefix for same-named props
 */
// Template syntax: :propName instead of :prop-name="propName"

// Configuration options
interface OptionsShortBind extends BaseOptions {
  /** Enable short bind syntax */
  enabled?: boolean;
}

Usage Examples:

<template>
  <!-- Standard prop binding -->
  <MyComponent :title="title" :count="count" :is-active="isActive" />
  
  <!-- Short bind syntax (same variable name as prop) -->
  <MyComponent :title :count :is-active />
  
  <!-- Mixed usage -->
  <MyComponent 
    :title           <!-- Short: same as :title="title" -->
    :count="newCount" <!-- Full: different variable name -->
    :is-active       <!-- Short: same as :is-active="isActive" -->
  />
  
  <!-- Works with kebab-case to camelCase conversion -->
  <MyComponent :user-name />  <!-- Same as :user-name="userName" -->
</template>

<script setup>
const title = ref('My Title');
const count = ref(10);
const newCount = ref(20);
const isActive = ref(true);
const userName = ref('john');
</script>

Boolean Props

Shorthand syntax for boolean props.

/**
 * Boolean prop syntax using + prefix
 */
// Template syntax: +propName instead of :prop-name="true"
// Template syntax: -propName instead of :prop-name="false"

// Configuration options
interface OptionsBooleanProp extends BaseOptions {
  /** Enable boolean prop syntax */
  enabled?: boolean;
}

Usage Examples:

<template>
  <!-- Standard boolean props -->
  <MyButton :disabled="true" :loading="false" />
  
  <!-- Boolean prop syntax -->
  <MyButton +disabled -loading />     <!-- Same as :disabled="true" :loading="false" -->
  
  <!-- Mixed with regular props -->
  <MyModal 
    +visible                          <!-- Same as :visible="true" -->
    -closeable                        <!-- Same as :closeable="false" -->
    title="My Modal"                  <!-- Regular prop -->
  />
  
  <!-- Conditional boolean props -->
  <MyComponent 
    +active="isActive"                <!-- Same as :active="isActive" -->
    +large="size === 'large'"         <!-- Same as :large="size === 'large'" -->
  />
</template>

<script setup>
const isActive = ref(true);
const size = ref('large');
</script>

Chain Call Destructuring

Enhanced destructuring for props with method chaining.

/**
 * Chain call destructuring for props
 */
declare const $defineProps: <T>() => ChainCallDestructure<T>;

interface ChainCallDestructure<T> {
  [K in keyof T]: PropChain<T[K]>;
}

interface PropChain<T> {
  /** Set default value */
  default(value: T | (() => T)): PropChain<T>;
  /** Mark as required */
  required(): PropChain<T>;
  /** Add validator function */
  validator(fn: (value: T) => boolean): PropChain<T>;
}

Usage Examples:

<script setup>
// Chain call destructuring
const { 
  title,
  count,
  user,
  options 
} = $defineProps<{
  title: string;
  count: number;
  user: { name: string; age: number };
  options: string[];
}>()
  .title.required()
  .count.default(0).validator(n => n >= 0)
  .user.default(() => ({ name: '', age: 0 }))
  .options.default(() => []);

// Direct usage in template and script
console.log(title);     // Type: string (required)
console.log(count);     // Type: number (default: 0)
console.log(user.name); // Type: string
console.log(options);   // Type: string[] (default: [])
</script>

Template Shortcuts

Additional template syntax shortcuts.

/**
 * Template syntax shortcuts and abbreviations
 */

// Event listener shortcuts
// @click -> v-on:click
// @input -> v-on:input

// Slot shortcuts  
// #default -> v-slot:default
// #header -> v-slot:header

// Directive shortcuts
// v-if -> v-if
// v-show -> v-show
// v-for -> v-for

Usage Examples:

<template>
  <!-- Event shortcuts (built into Vue) -->
  <button @click="handleClick">Click</button>
  <input @input="handleInput" @change="handleChange" />
  
  <!-- Slot shortcuts (built into Vue) -->
  <MyComponent>
    <template #header="{ title }">
      <h1>{{ title }}</h1>
    </template>
    
    <template #default>
      <p>Default content</p>
    </template>
    
    <template #footer>
      <p>Footer content</p>
    </template>
  </MyComponent>
  
  <!-- Short syntax combinations -->
  <MyCard 
    +visible          <!-- Boolean prop -->
    :title            <!-- Short bind -->
    ::selected        <!-- Short v-model -->
    @close="onClose"  <!-- Event -->
  />
</template>

<script setup>
const title = ref('Card Title');
const selected = ref(false);

function handleClick() {
  console.log('Clicked');
}

function handleInput(event: Event) {
  console.log('Input:', (event.target as HTMLInputElement).value);
}

function handleChange(event: Event) {
  console.log('Changed:', (event.target as HTMLInputElement).value);
}

function onClose() {
  console.log('Card closed');
}
</script>

Macro Combinations

Combining multiple syntax sugar features.

/**
 * Combined syntax sugar usage patterns
 */

// Combining short bind + boolean props + short v-model
// <Component :title +active ::value @event="handler" />

// Combining chain call + short syntax
// const { prop } = $defineProps<T>().prop.default(value);

Usage Examples:

<template>
  <!-- All syntax sugar combined -->
  <AdvancedComponent
    :title              <!-- Short bind -->
    :count="newCount"   <!-- Regular bind -->
    +visible            <!-- Boolean prop (true) -->
    -disabled           <!-- Boolean prop (false) -->
    ::modelValue        <!-- Short v-model -->
    ::checked           <!-- Short v-model named -->
    @update="onUpdate"  <!-- Event handler -->
    @close="onClose"    <!-- Event handler -->
  >
    <template #header="{ data }">
      <h2>{{ data.title }}</h2>
    </template>
  </AdvancedComponent>
</template>

<script setup>
// Combined prop definition with syntax sugar
const {
  title,
  description,
  count,
  isActive
} = $defineProps<{
  title: string;
  description?: string;
  count: number;
  isActive: boolean;
}>()
  .title.required()
  .description.default('No description')
  .count.default(0).validator(n => n >= 0)
  .isActive.default(true);

// Short emits
const emit = defineEmits<{
  update: [value: any];
  close: [];
}>();

// Usage
const newCount = ref(42);
const modelValue = ref('');
const checked = ref(false);

function onUpdate(value: any) {
  emits('update', value);  // Short emit syntax
}

function onClose() {
  emits('close');          // Short emit syntax
}
</script>

Type Definitions

Supporting types for syntax sugar features.

// Configuration base
interface BaseOptions {
  version?: string;
  isProduction?: boolean;
  root?: string;
  include?: string | RegExp | (string | RegExp)[];
  exclude?: string | RegExp | (string | RegExp)[];
}

// Emit function type
type EmitFunction<T> = T extends Record<string, any>
  ? <K extends keyof T>(event: K, ...args: T[K] extends (...args: infer P) => any ? P : [T[K]]) => void
  : (event: string, ...args: any[]) => void;

// Props chain utilities
type PropValidation<T> = {
  type?: PropType<T>;
  required?: boolean;
  default?: T | (() => T);
  validator?: (value: T) => boolean;
};

// Template syntax type utilities
type BooleanPropValue<T> = T extends boolean ? T : boolean;
type ShortBindValue<T> = T;
type VModelValue<T> = T;

// Syntax sugar combination types
type SugarProps<T> = {
  [K in keyof T]: T[K] extends boolean 
    ? BooleanPropValue<T[K]>
    : ShortBindValue<T[K]>;
};

Install with Tessl CLI

npx tessl i tessl/npm-unplugin-vue-macros

docs

advanced-features.md

component-definition.md

configuration.md

index.md

props-models.md

syntax-sugar.md

tile.json