CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-vue-demi

Vue Demi is a developing utility that allows you to write Universal Vue Libraries for Vue 2 & 3

Pending
Overview
Eval results
Files

composition-api.mddocs/

Composition API

Universal access to Composition API functions that work across Vue 2 (with @vue/composition-api) and Vue 3. Vue Demi automatically provides the appropriate implementation based on the detected Vue version.

Capabilities

Safe Installation

Ensures the Composition API plugin is properly installed. This is a no-op in Vue 3 but safely installs @vue/composition-api in Vue 2 environments.

/**
 * Safe installation of Composition API plugin
 * No-op in Vue 3, installs @vue/composition-api in Vue 2
 * @param vue - Optional Vue constructor (Vue 2 only), ignored in Vue 3
 */
declare function install(vue?: typeof Vue): void; // Vue 2: (vue?: typeof Vue), Vue 3: () => void

Usage Examples:

import { install } from "vue-demi";

// Ensure Composition API is available
install();

// Or with specific Vue instance
import Vue from 'vue';
install(Vue);

// Safe to call multiple times
install();
install(); // No-op if already installed

Universal Composition API

All Composition API functions are re-exported from vue-demi, providing a universal interface that works across Vue versions.

// Core reactivity
export function ref<T>(value: T): Ref<T>;
export function reactive<T extends object>(target: T): UnwrapNestedRefs<T>;
export function computed<T>(getter: () => T): ComputedRef<T>;
export function readonly<T>(target: T): DeepReadonly<T>;

// Watchers
export function watch<T>(
  source: WatchSource<T>,
  callback: WatchCallback<T>,
  options?: WatchOptions
): WatchStopHandle;

export function watchEffect(
  effect: WatchEffect,
  options?: WatchOptionsBase
): WatchStopHandle;

// Lifecycle hooks
export function onMounted(hook: () => any): void;
export function onUpdated(hook: () => any): void;
export function onUnmounted(hook: () => any): void;
export function onBeforeMount(hook: () => any): void;
export function onBeforeUpdate(hook: () => any): void;
export function onBeforeUnmount(hook: () => any): void;

// Dependency injection
export function provide<T>(key: InjectionKey<T> | string, value: T): void;
export function inject<T>(key: InjectionKey<T> | string): T | undefined;
export function inject<T>(key: InjectionKey<T> | string, defaultValue: T): T;

// Component utilities
export function getCurrentInstance(): ComponentInternalInstance | null;
export function nextTick(fn?: () => void): Promise<void>;
export function hasInjectionContext(): boolean;

Usage Examples:

import { 
  ref, 
  reactive, 
  computed, 
  watch, 
  onMounted, 
  install 
} from "vue-demi";

// Ensure Composition API is installed
install();

export default {
  setup() {
    // Reactive state
    const count = ref(0);
    const user = reactive({
      name: 'John',
      email: 'john@example.com'
    });
    
    // Computed values
    const doubleCount = computed(() => count.value * 2);
    
    // Watchers
    watch(count, (newVal, oldVal) => {
      console.log(`Count changed from ${oldVal} to ${newVal}`);
    });
    
    // Lifecycle
    onMounted(() => {
      console.log('Component mounted');
    });
    
    return {
      count,
      user,
      doubleCount
    };
  }
};

Vue 3 Component Mocks (Vue 2 only)

In Vue 2 environments, Vue 3 specific components are provided as mock implementations that throw helpful errors to prevent runtime issues.

/**
 * Mock components for Vue 3 features not available in Vue 2
 * These throw descriptive errors when used in Vue 2
 */
export declare const Fragment: Component;
export declare const Transition: Component;
export declare const TransitionGroup: Component;
export declare const Teleport: Component;
export declare const Suspense: Component;
export declare const KeepAlive: Component;

Usage Examples:

import { Fragment, isVue2 } from "vue-demi";

// Safe conditional usage
const MyComponent = {
  setup() {
    if (isVue2) {
      // Vue 2 implementation without Fragment
      return () => h('div', [
        h('p', 'First paragraph'),
        h('p', 'Second paragraph')
      ]);
    } else {
      // Vue 3 implementation with Fragment
      return () => h(Fragment, [
        h('p', 'First paragraph'),
        h('p', 'Second paragraph')
      ]);
    }
  }
};

// This would throw an error in Vue 2:
// [vue-demi] Fragment is not supported in Vue 2. It's provided to avoid compiler errors.

Injection Context Check

Utility to check if injection context is available, useful for safely using provide/inject.

/**
 * Check if injection context exists
 * Falls back to getCurrentInstance() check
 * @returns boolean indicating if injection context is available
 */
export function hasInjectionContext(): boolean;

Usage Examples:

import { hasInjectionContext, inject, provide } from "vue-demi";

// Safe injection usage
function useTheme() {
  if (hasInjectionContext()) {
    return inject('theme', 'light');
  }
  return 'light'; // fallback
}

// Conditional provide/inject
export default {
  setup() {
    if (hasInjectionContext()) {
      provide('theme', 'dark');
    }
    
    const theme = useTheme();
    return { theme };
  }
};

Vue Warning Utility (Vue 2.7 only)

Vue 2.7 provides access to Vue's internal warning utility for development debugging.

/**
 * Vue warning function (Vue 2.7 only)
 * Emits development warnings with optional component context
 * @param msg - Warning message to display
 * @param vm - Optional component instance for context
 */
export declare function warn(msg: string, vm?: Component | null): void;

Usage Examples:

import { warn, isVue2, version } from "vue-demi";

// Development warnings (Vue 2.7 only)
export default {
  setup() {
    if (process.env.NODE_ENV !== 'production' && isVue2 && version?.startsWith('2.7')) {
      // Emit warning with component context
      warn('This is a development warning', getCurrentInstance());
      
      // Simple warning
      warn('Configuration issue detected');
    }
    
    return {};
  }
};

// Conditional warning utility
function devWarn(message: string, component?: any) {
  if (process.env.NODE_ENV !== 'production' && typeof warn === 'function') {
    warn(message, component);
  } else {
    console.warn(message);
  }
}

Vue 2.7 App Creation Polyfill

For Vue 2.7, vue-demi provides a polyfill for Vue 3's createApp API.

/**
 * Create Vue 3 style app instance (Vue 2.7 only)
 * Polyfill that wraps Vue 2 constructor with Vue 3 app interface
 */
export function createApp(rootComponent: any, rootProps?: any): App;

interface App<T = any> {
  config: VueConstructor['config'];
  use: VueConstructor['use'];
  mixin: VueConstructor['mixin'];
  component: VueConstructor['component'];
  directive(name: string): Directive | undefined;
  directive(name: string, directive: Directive): this;
  provide<T>(key: InjectionKey<T> | string, value: T): this;
  mount: Vue['$mount'];
  unmount: Vue['$destroy'];
}

Usage Examples (Vue 2.7 only):

import { createApp, isVue2 } from "vue-demi";

const MyComponent = {
  template: '<div>{{ message }}</div>',
  data() {
    return { message: 'Hello Vue!' };
  }
};

// Vue 2.7 with createApp polyfill
if (isVue2) {
  const app = createApp(MyComponent);
  app.provide('theme', 'dark');
  app.mount('#app');
}

Install with Tessl CLI

npx tessl i tessl/npm-vue-demi

docs

cli-tools.md

composition-api.md

index.md

reactive-utilities.md

version-detection.md

tile.json