CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-vue-router

Official router for Vue.js 2 providing declarative routing, navigation guards, and nested route configuration.

Pending
Overview
Eval results
Files

composables.mddocs/

Composition API

Vue 3-style composables for accessing router functionality in composition API components. These functions provide reactive access to router state and navigation controls for use with Vue 2.7+ composition API or @vue/composition-api plugin.

import { useRouter, useRoute, onBeforeRouteUpdate, onBeforeRouteLeave, useLink } from 'vue-router/composables';

Capabilities

Core Composables

Access router instance and current route reactively.

/**
 * Access the router instance
 * @returns VueRouter instance
 */
function useRouter(): VueRouter;

/**
 * Access the current route (reactive)
 * @returns Reactive route object that updates when route changes
 */
function useRoute(): Route;

Usage Examples:

import { useRouter, useRoute } from 'vue-router/composables';
import { computed, watch } from 'vue';

export default {
  setup() {
    const router = useRouter();
    const route = useRoute();
    
    // Reactive route properties
    const userId = computed(() => route.params.id);
    const currentPath = computed(() => route.path);
    const queryParams = computed(() => route.query);
    
    // Watch route changes
    watch(() => route.params.id, (newId, oldId) => {
      console.log(`User changed from ${oldId} to ${newId}`);
      loadUserData(newId);
    });
    
    // Navigation methods
    const navigateToUser = (id) => {
      router.push({ name: 'user', params: { id }});
    };
    
    const goBack = () => {
      router.go(-1);
    };
    
    return {
      userId,
      currentPath,
      queryParams,
      navigateToUser,
      goBack
    };
  }
};

Navigation Guards Composables

Register navigation guards that are automatically cleaned up when component is unmounted.

/**
 * Register guard for route updates (when component is reused)
 * @param guard - Navigation guard function
 */
function onBeforeRouteUpdate(guard: NavigationGuard): void;

/**
 * Register guard for leaving current route
 * @param guard - Navigation guard function
 */
function onBeforeRouteLeave(guard: NavigationGuard): void;

Usage Examples:

import { onBeforeRouteUpdate, onBeforeRouteLeave } from 'vue-router/composables';
import { ref, onMounted } from 'vue';

export default {
  setup() {
    const userData = ref(null);
    const hasUnsavedChanges = ref(false);
    const loading = ref(false);
    
    // Handle route parameter changes
    onBeforeRouteUpdate(async (to, from, next) => {
      if (to.params.id !== from.params.id) {
        loading.value = true;
        try {
          userData.value = await fetchUser(to.params.id);
          next();
        } catch (error) {
          console.error('Failed to load user:', error);
          next(false); // Cancel navigation
        } finally {
          loading.value = false;
        }
      } else {
        next();
      }
    });
    
    // Prevent leaving with unsaved changes
    onBeforeRouteLeave((to, from, next) => {
      if (hasUnsavedChanges.value) {
        const confirmed = window.confirm(
          'You have unsaved changes. Are you sure you want to leave?'
        );
        next(confirmed);
      } else {
        next();
      }
    });
    
    const saveChanges = async () => {
      // Save logic
      hasUnsavedChanges.value = false;
    };
    
    return {
      userData,
      hasUnsavedChanges,
      loading,
      saveChanges
    };
  }
};

Link Composable

Access RouterLink functionality programmatically with reactive state.

/**
 * RouterLink composable options
 */
interface RouterLinkOptions {
  /** Route location to link to */
  to: Route | Ref<Route>;
  /** Use replace instead of push */
  replace?: boolean;
}

/**
 * RouterLink functionality as composable
 * @param options - Link configuration
 * @returns Reactive link state and navigation function
 */
function useLink(options: RouterLinkOptions): {
  /** Computed route object */
  route: ComputedRef<Route>;
  /** Whether link is active */
  isActive: ComputedRef<boolean>;
  /** Whether link is exact active */
  isExactActive: ComputedRef<boolean>;
  /** Resolved href */
  href: ComputedRef<string>;
  /** Navigation function */
  navigate: () => Promise<void>;
};

Usage Examples:

import { useLink } from 'vue-router/composables';
import { ref, computed } from 'vue';

export default {
  setup() {
    const selectedUser = ref('123');
    
    // Dynamic link based on reactive data
    const userLink = useLink({
      to: computed(() => ({ 
        name: 'user', 
        params: { id: selectedUser.value }
      }))
    });
    
    // Custom navigation with confirmation
    const handleNavigation = async () => {
      const confirmed = await showConfirmDialog('Navigate to user?');
      if (confirmed) {
        userLink.navigate();
      }
    };
    
    // Multiple links
    const links = computed(() => [
      useLink({ to: { name: 'home' }}),
      useLink({ to: { name: 'about' }}),
      useLink({ to: { name: 'contact' }})
    ]);
    
    return {
      selectedUser,
      userLink,
      handleNavigation,
      links
    };
  }
};

Route Information Composables

Extract specific route information reactively.

/**
 * Utility composables for common route data access patterns
 */
function useRouteParams(): ComputedRef<Dictionary<string>>;
function useRouteQuery(): ComputedRef<Dictionary<string | (string | null)[]>>;
function useRoutePath(): ComputedRef<string>;
function useRouteName(): ComputedRef<string | null | undefined>;

Usage Examples:

// Custom utility composables (can be created)
import { useRoute } from 'vue-router/composables';
import { computed } from 'vue';

// Create reusable route utilities
function useRouteParams() {
  const route = useRoute();
  return computed(() => route.params);
}

function useRouteQuery() {
  const route = useRoute();
  return computed(() => route.query);
}

function useRoutePath() {
  const route = useRoute();
  return computed(() => route.path);
}

export default {
  setup() {
    const params = useRouteParams();
    const query = useRouteQuery();
    const path = useRoutePath();
    
    // Type-safe parameter access
    const userId = computed(() => params.value.id);
    const tab = computed(() => query.value.tab || 'profile');
    
    // Derived state
    const breadcrumbs = computed(() => 
      path.value.split('/').filter(Boolean).map((segment, i, arr) => ({
        name: segment,
        path: '/' + arr.slice(0, i + 1).join('/')
      }))
    );
    
    return {
      userId,
      tab,
      breadcrumbs
    };
  }
};

Navigation Composables

Create reusable navigation functions.

/**
 * Navigation utility composables
 */
function useNavigation(): {
  push: (to: RawLocation) => Promise<Route>;
  replace: (to: RawLocation) => Promise<Route>;
  go: (n: number) => void;
  back: () => void;
  forward: () => void;
};

Usage Examples:

import { useRouter } from 'vue-router/composables';

// Create navigation utilities
function useNavigation() {
  const router = useRouter();
  
  return {
    push: (to) => router.push(to),
    replace: (to) => router.replace(to),
    go: (n) => router.go(n),
    back: () => router.back(),
    forward: () => router.forward()
  };
}

// Specialized navigation composables
function useUserNavigation() {
  const { push } = useNavigation();
  
  const goToUser = (id) => push({ name: 'user', params: { id }});
  const goToUserEdit = (id) => push({ name: 'user-edit', params: { id }});
  const goToUserPosts = (id) => push({ name: 'user-posts', params: { id }});
  
  return {
    goToUser,
    goToUserEdit,
    goToUserPosts
  };
}

export default {
  setup() {
    const { back, forward } = useNavigation();
    const { goToUser } = useUserNavigation();
    
    const handleUserClick = (user) => {
      goToUser(user.id);
    };
    
    return {
      back,
      forward,
      handleUserClick
    };
  }
};

Setup and Installation

Using composables with Vue 2.7+ or composition API plugin.

/**
 * Installation requirements for composables
 */
interface ComposableSetup {
  /** Vue 2.7+ has built-in composition API */
  vue27Plus: boolean;
  /** Or use @vue/composition-api plugin */
  compositionApiPlugin: boolean;
}

Usage Examples:

// With Vue 2.7+
import { createApp } from 'vue';
import VueRouter from 'vue-router';

const app = createApp({});
app.use(VueRouter);

// With @vue/composition-api plugin (Vue < 2.7)
import Vue from 'vue';
import VueCompositionApi from '@vue/composition-api';
import VueRouter from 'vue-router';

Vue.use(VueCompositionApi);
Vue.use(VueRouter);

// Component using composables
import { useRouter, useRoute } from 'vue-router/composables';

export default {
  setup() {
    // Must be called inside setup() function
    const router = useRouter();
    const route = useRoute();
    
    // Error: Cannot be called outside setup()
    // const router = useRouter(); // This would throw error
    
    return {
      // Expose to template if needed
    };
  }
};

Error Handling with Composables

Handle navigation errors in composition API context.

/**
 * Error handling patterns for composables
 */
interface ComposableErrorHandling {
  navigationErrors: Promise<NavigationFailure | undefined>;
  guardErrors: Error | NavigationFailure;
}

Usage Examples:

import { useRouter } from 'vue-router/composables';
import { isNavigationFailure, NavigationFailureType } from 'vue-router';
import { ref } from 'vue';

export default {
  setup() {
    const router = useRouter();
    const navigationError = ref(null);
    
    const navigateWithErrorHandling = async (to) => {
      try {
        await router.push(to);
        navigationError.value = null;
      } catch (error) {
        if (isNavigationFailure(error, NavigationFailureType.aborted)) {
          console.log('Navigation was aborted');
        } else if (isNavigationFailure(error, NavigationFailureType.duplicated)) {
          console.log('Already at destination');
        } else {
          navigationError.value = error;
          console.error('Navigation failed:', error);
        }
      }
    };
    
    // Guard error handling
    onBeforeRouteLeave((to, from, next) => {
      try {
        // Some validation that might throw
        validateBeforeLeave();
        next();
      } catch (error) {
        console.error('Leave guard error:', error);
        next(false);
      }
    });
    
    return {
      navigateWithErrorHandling,
      navigationError
    };
  }
};

Types

interface ComputedRef<T> {
  readonly value: T;
}

interface Ref<T> {
  value: T;
}

type Dictionary<T> = { [key: string]: T };

interface NavigationGuard {
  (to: Route, from: Route, next: NavigationGuardNext): any;
}

type NavigationGuardNext = (to?: RawLocation | false | ((vm: Vue) => any) | void) => void;

Install with Tessl CLI

npx tessl i tessl/npm-vue-router

docs

components.md

composables.md

index.md

navigation-guards.md

route-configuration.md

router-instance.md

tile.json