While UniApp does not provide a built-in navigation guard system like Vue Router, you can simulate this behavior by wrapping the native navigation APIs. By intercepting calls to uni.navigateTo, uni.switchTab, and other methods, you can inject custom logic such as authentication checks or logging before a page transition occurs.
Step 1: Creating a Custom Navigation Wrapper
Create a utility module that mirrors the native UniApp routing methods. Inside these wrappers, call a "before hook" function to determine if the navigation should proceed.
// utils/navGuard.js
// Mock authentication check
function isAuthenticated() {
const userInfo = uni.getStorageSync('userInfo');
return userInfo !== '' && userInfo !== null;
}
// Mock permission check
function hasPermission(role) {
const userInfo = uni.getStorageSync('userInfo');
return userInfo && userInfo.role === role;
}
// The guard logic
function routeGuard(targetUrl) {
// 1. Check for protected areas
if (targetUrl.startsWith('/pages/dashboard')) {
if (!isAuthenticated()) {
uni.showToast({ title: 'Session expired. Please login.', icon: 'none' });
uni.redirectTo({ url: '/pages/auth/login' });
return false;
}
}
// 2. Check for admin-only sections
if (targetUrl.startsWith('/pages/admin')) {
if (!hasPermission('admin')) {
uni.showToast({ title: 'Access Denied', icon: 'none' });
return false;
}
}
// 3. Log the visit
const logs = uni.getStorageSync('navLogs') || [];
logs.push({ path: targetUrl, time: new Date().toISOString() });
uni.setStorageSync('navLogs', logs);
return true;
}
// Wrapped navigation methods
function pushPage(config) {
if (routeGuard(config.url)) {
uni.navigateTo(config);
}
}
function replacePage(config) {
if (routeGuard(config.url)) {
uni.redirectTo(config);
}
}
function switchTabBar(config) {
// Note: switchTab usually doesn't pass complex params, just url
if (routeGuard(config.url)) {
uni.switchTab(config);
}
}
function restartApp(config) {
if (routeGuard(config.url)) {
uni.reLaunch(config);
}
}
function goBack(config) {
// navigateBack doesn't usually have a URL, but we can run a generic check
uni.navigateBack(config);
}
export default {
pushPage,
replacePage,
switchTabBar,
restartApp,
goBack
};
Step 2: Integrating in Components
Instead of using the global uni methods directly, import your custom wrapper to ensure the guards are triggered.
// pages/index/index.vue
<template>
<view>
<button @click="enterAdminPanel">Enter Admin</button>
<button @click="viewDashboard">View Dashboard</button>
</view>
</template>
<script>
import guard from '@/utils/navGuard';
export default {
methods: {
enterAdminPanel() {
guard.pushPage({
url: '/pages/admin/settings'
});
},
viewDashboard() {
guard.switchTabBar({
url: '/pages/dashboard/main'
});
}
}
};
</script>
Step 3: Global Injection (Optional)
To make the guarded methods available throughout the app without multiple imports, you can attach them to the global uni object or a Vue prototpye in your entry file.
// main.js
import guard from '@/utils/navGuard';
// Attach to global context
uni.$nav = guard;
// Usage elsewhere: uni.$nav.pushPage({ url: '...' })
Comparison: UniApp vs. Vue Router
Understanding the difference in routing philosophy helps in structuring your app:
| Feature | UniApp (Custom Guards) | Vue + Vue Router |
|---|---|---|
| Configuration | Defined in pages.json |
Defined in JavaScript (Router Instance) |
| Guard Mechainsm | Manual wrapping of APIs | Built-in beforeEach / afterEach |
| Platform | Cross-platform (Mobile/Web/Applets) | Primarily Web SPA |
| Component Integration | API-based page switching | Component-based via <router-view> |
Native UniApp Routing Configuration
UniApp relies on a static configuration file for registering pages.
// pages.json
{
"pages": [
{
"path": "pages/index/index",
"style": { "navigationBarTitleText": "Home" }
},
{
"path": "pages/dashboard/main",
"style": { "navigationBarTitleText": "Dashboard" }
}
],
"tabBar": {
"list": [
{ "pagePath": "pages/index/index", "text": "Home" },
{ "pagePath": "pages/dashboard/main", "text": "Stats" }
]
}
}
Native Navigation Examples
If not using the wrapper, these are the standard APIs provided by the framework:
// Standard jump
uni.navigateTo({ url: '/pages/index/index' });
// Tab switch
uni.switchTab({ url: '/pages/dashboard/main' });
// Close current and jump
uni.redirectTo({ url: '/pages/login/login' });