Skip to content

Router

uni-app uses a page-based routing system. Each page corresponds to a Vue component, and routing is managed through configuration and API calls.

Page Route Configuration

pages.json Configuration

All page routes are configured in the pages.json file:

json
{
  "pages": [
    {
      "path": "pages/index/index",
      "style": {
        "navigationBarTitleText": "Home"
      }
    },
    {
      "path": "pages/about/about",
      "style": {
        "navigationBarTitleText": "About"
      }
    }
  ],
  "globalStyle": {
    "navigationBarTextStyle": "black",
    "navigationBarTitleText": "uni-app",
    "navigationBarBackgroundColor": "#F8F8F8",
    "backgroundColor": "#F8F8F8"
  }
}

Page Path Rules

  • Page paths are relative to the project root directory
  • The first page in the pages array is the application's home page
  • Page paths do not include file extensions
  • Each page must have a corresponding Vue file

Route Navigation

Declarative Navigation

Use the navigator component for declarative navigation:

vue
<template>
  <view>
    <!-- Navigate to a page -->
    <navigator url="/pages/about/about">Go to About</navigator>
    
    <!-- Navigate with parameters -->
    <navigator url="/pages/detail/detail?id=123&name=test">
      Go to Detail
    </navigator>
    
    <!-- Tab switching -->
    <navigator url="/pages/home/home" open-type="switchTab">
      Switch to Home Tab
    </navigator>
    
    <!-- Redirect (replace current page) -->
    <navigator url="/pages/login/login" open-type="redirect">
      Go to Login
    </navigator>
  </view>
</template>

Programmatic Navigation

Use API methods for programmatic navigation:

uni.navigateTo()

Navigate to a new page while keeping the current page in the page stack:

javascript
// Basic navigation
uni.navigateTo({
  url: '/pages/detail/detail'
});

// Navigation with parameters
uni.navigateTo({
  url: '/pages/detail/detail?id=123&name=test',
  success: function(res) {
    console.log('Navigation successful');
  },
  fail: function(err) {
    console.log('Navigation failed');
  }
});

// Navigation with events
uni.navigateTo({
  url: '/pages/detail/detail',
  events: {
    // Listen for data from the opened page
    acceptDataFromOpenedPage: function(data) {
      console.log(data);
    }
  },
  success: function(res) {
    // Send data to the opened page
    res.eventChannel.emit('acceptDataFromOpenerPage', { data: 'from opener page' });
  }
});

uni.redirectTo()

Close the current page and navigate to a new page:

javascript
uni.redirectTo({
  url: '/pages/login/login'
});

uni.reLaunch()

Close all pages and navigate to a new page:

javascript
uni.reLaunch({
  url: '/pages/home/home'
});

uni.switchTab()

Switch to a tab page:

javascript
uni.switchTab({
  url: '/pages/home/home'
});

uni.navigateBack()

Navigate back to the previous page:

javascript
// Go back one page
uni.navigateBack();

// Go back multiple pages
uni.navigateBack({
  delta: 2 // Go back 2 pages
});

Parameter Passing

URL Parameters

Pass parameters through URL query strings:

javascript
// Sender page
uni.navigateTo({
  url: '/pages/detail/detail?id=123&name=test&type=product'
});
javascript
// Receiver page
export default {
  onLoad(options) {
    console.log(options.id);    // 123
    console.log(options.name);  // test
    console.log(options.type);  // product
  }
}

Event Channel Communication

Use event channels for complex data passing:

javascript
// Sender page
uni.navigateTo({
  url: '/pages/detail/detail',
  events: {
    // Listen for data from the opened page
    acceptDataFromOpenedPage: function(data) {
      console.log('Received data:', data);
    },
    someEvent: function(data) {
      console.log('Some event triggered:', data);
    }
  },
  success: function(res) {
    // Send data to the opened page
    res.eventChannel.emit('acceptDataFromOpenerPage', { 
      user: { id: 1, name: 'John' },
      products: [1, 2, 3]
    });
  }
});
javascript
// Receiver page
export default {
  onLoad() {
    // Get event channel
    const eventChannel = this.getOpenerEventChannel();
    
    // Listen for data from opener page
    eventChannel.on('acceptDataFromOpenerPage', function(data) {
      console.log('Received data from opener:', data);
    });
    
    // Send data back to opener page
    eventChannel.emit('acceptDataFromOpenedPage', { result: 'success' });
  }
}

Route Interception

Global Route Interception

Intercept route navigation globally:

javascript
// main.js
import { createSSRApp } from 'vue'
import App from './App.vue'

export function createApp() {
  const app = createSSRApp(App)
  
  // Add route interception
  const originalNavigateTo = uni.navigateTo;
  uni.navigateTo = function(options) {
    // Check login status
    const token = uni.getStorageSync('token');
    if (!token && options.url.includes('/pages/user/')) {
      // Redirect to login if not authenticated
      return originalNavigateTo({
        url: '/pages/login/login'
      });
    }
    return originalNavigateTo(options);
  };
  
  return {
    app
  }
}

Page-level Route Guards

Implement route guards at the page level:

javascript
export default {
  onLoad() {
    // Check permissions before page loads
    this.checkPermissions();
  },
  
  methods: {
    checkPermissions() {
      const userRole = uni.getStorageSync('userRole');
      if (userRole !== 'admin') {
        uni.showToast({
          title: 'Access denied',
          icon: 'none'
        });
        uni.navigateBack();
      }
    }
  }
}

Page Stack Management

Understanding Page Stack

uni-app maintains a page stack to manage page navigation:

  • navigateTo: Pushes a new page onto the stack
  • redirectTo: Replaces the current page
  • navigateBack: Pops pages from the stack
  • reLaunch: Clears the stack and pushes a new page
  • switchTab: Special handling for tab pages

Page Stack Limits

Different platforms have different page stack limits:

  • Mini Programs: Maximum 10 pages
  • App: No strict limit, but too many pages may affect performance
  • H5: Depends on browser memory

Managing Page Stack

javascript
// Get current page stack
const pages = getCurrentPages();
console.log('Current page count:', pages.length);
console.log('Current page:', pages[pages.length - 1]);

// Check if can go back
if (pages.length > 1) {
  uni.navigateBack();
} else {
  uni.reLaunch({
    url: '/pages/home/home'
  });
}

Tab Bar Navigation

Tab Bar Configuration

Configure tab bar in pages.json:

json
{
  "tabBar": {
    "color": "#7A7E83",
    "selectedColor": "#3cc51f",
    "borderStyle": "black",
    "backgroundColor": "#ffffff",
    "list": [
      {
        "pagePath": "pages/home/home",
        "iconPath": "static/home.png",
        "selectedIconPath": "static/home-active.png",
        "text": "Home"
      },
      {
        "pagePath": "pages/category/category",
        "iconPath": "static/category.png",
        "selectedIconPath": "static/category-active.png",
        "text": "Category"
      },
      {
        "pagePath": "pages/user/user",
        "iconPath": "static/user.png",
        "selectedIconPath": "static/user-active.png",
        "text": "Profile"
      }
    ]
  }
}

Tab Bar Navigation

javascript
// Switch to tab page
uni.switchTab({
  url: '/pages/home/home'
});

// Programmatically set tab bar badge
uni.setTabBarBadge({
  index: 1,
  text: '3'
});

// Remove tab bar badge
uni.removeTabBarBadge({
  index: 1
});

Dynamic Routing

Dynamic Route Parameters

Handle dynamic route parameters:

javascript
// Navigate with dynamic parameters
const userId = 123;
uni.navigateTo({
  url: `/pages/user/profile?userId=${userId}`
});
javascript
// Handle dynamic parameters
export default {
  data() {
    return {
      userId: null,
      userInfo: null
    }
  },
  
  onLoad(options) {
    this.userId = options.userId;
    this.loadUserInfo();
  },
  
  methods: {
    async loadUserInfo() {
      try {
        const res = await this.$http.get(`/api/users/${this.userId}`);
        this.userInfo = res.data;
      } catch (error) {
        console.error('Failed to load user info:', error);
      }
    }
  }
}

Route Animation

Custom Page Transitions

Configure page transition animations:

json
{
  "pages": [
    {
      "path": "pages/detail/detail",
      "style": {
        "navigationBarTitleText": "Detail",
        "animationType": "slide-in-right",
        "animationDuration": 300
      }
    }
  ]
}

Programmatic Animations

javascript
uni.navigateTo({
  url: '/pages/detail/detail',
  animationType: 'slide-in-bottom',
  animationDuration: 200
});

Best Practices

1. Route Organization

javascript
// Create a route helper
class RouteHelper {
  static navigateToDetail(id) {
    uni.navigateTo({
      url: `/pages/detail/detail?id=${id}`
    });
  }
  
  static navigateToUser(userId) {
    uni.navigateTo({
      url: `/pages/user/profile?userId=${userId}`
    });
  }
  
  static goBack(delta = 1) {
    const pages = getCurrentPages();
    if (pages.length > delta) {
      uni.navigateBack({ delta });
    } else {
      uni.reLaunch({
        url: '/pages/home/home'
      });
    }
  }
}

// Usage
RouteHelper.navigateToDetail(123);

2. Parameter Validation

javascript
export default {
  onLoad(options) {
    // Validate required parameters
    if (!options.id) {
      uni.showToast({
        title: 'Invalid parameters',
        icon: 'none'
      });
      uni.navigateBack();
      return;
    }
    
    this.loadData(options.id);
  }
}

3. Error Handling

javascript
const navigateWithErrorHandling = (options) => {
  uni.navigateTo({
    ...options,
    fail: (err) => {
      console.error('Navigation failed:', err);
      uni.showToast({
        title: 'Navigation failed',
        icon: 'none'
      });
    }
  });
};

4. Deep Linking Support

javascript
// Handle deep links
export default {
  onLaunch(options) {
    // Handle app launch from deep link
    if (options.path) {
      this.handleDeepLink(options.path, options.query);
    }
  },
  
  methods: {
    handleDeepLink(path, query) {
      // Parse and navigate to the appropriate page
      const url = this.buildUrl(path, query);
      uni.reLaunch({ url });
    },
    
    buildUrl(path, query) {
      const queryString = Object.keys(query)
        .map(key => `${key}=${query[key]}`)
        .join('&');
      return queryString ? `${path}?${queryString}` : path;
    }
  }
}

Platform Differences

Mini Program Limitations

javascript
// #ifdef MP
// Mini program specific route handling
if (getCurrentPages().length >= 10) {
  // Redirect instead of navigate when stack is full
  uni.redirectTo({
    url: '/pages/detail/detail'
  });
} else {
  uni.navigateTo({
    url: '/pages/detail/detail'
  });
}
// #endif

// #ifdef H5
// H5 specific route handling
uni.navigateTo({
  url: '/pages/detail/detail'
});
// #endif

App-specific Features

javascript
// #ifdef APP-PLUS
// App-specific route animations
uni.navigateTo({
  url: '/pages/detail/detail',
  animationType: 'slide-in-right',
  animationDuration: 300
});
// #endif

This routing system provides a comprehensive solution for navigation in uni-app applications, supporting various navigation patterns and platform-specific optimizations.

一次开发,多端部署 - 让跨平台开发更简单