Backbone.js路由配置 #
一、路由规则 #
1.1 routes对象 #
javascript
var AppRouter = Backbone.Router.extend({
routes: {
'': 'home',
'about': 'about',
'users': 'users',
'users/:id': 'userDetail'
}
});
1.2 动态添加路由 #
javascript
var router = new Backbone.Router();
router.route('posts/:id', 'showPost', function(id) {
console.log('文章ID:', id);
});
router.route('categories/:category/posts/:id', 'showCategoryPost', function(category, id) {
console.log('分类:', category, '文章ID:', id);
});
1.3 函数形式的routes #
javascript
var AppRouter = Backbone.Router.extend({
routes: function() {
var routes = {
'': 'home',
'about': 'about'
};
if (this.options.enableAdmin) {
routes['admin'] = 'admin';
routes['admin/users'] = 'adminUsers';
}
return routes;
}
});
二、参数类型 #
2.1 基本参数 #
javascript
var AppRouter = Backbone.Router.extend({
routes: {
'users/:id': 'showUser'
},
showUser: function(id) {
console.log('用户ID:', id);
}
});
2.2 多个参数 #
javascript
var AppRouter = Backbone.Router.extend({
routes: {
'posts/:year/:month/:day': 'showPost'
},
showPost: function(year, month, day) {
console.log('日期:', year, month, day);
}
});
2.3 通配符参数 #
javascript
var AppRouter = Backbone.Router.extend({
routes: {
'files/*path': 'showFile',
'search/*query': 'search'
},
showFile: function(path) {
console.log('文件路径:', path);
},
search: function(query) {
console.log('搜索词:', query);
}
});
2.4 可选参数 #
javascript
var AppRouter = Backbone.Router.extend({
routes: {
'products(/:category)(/sort/:sort)': 'products',
'users(/page/:page)': 'users'
},
products: function(category, sort) {
category = category || 'all';
sort = sort || 'default';
console.log('分类:', category, '排序:', sort);
},
users: function(page) {
page = page || 1;
console.log('页码:', page);
}
});
2.5 参数约束 #
javascript
var AppRouter = Backbone.Router.extend({
initialize: function() {
this.route(/^users\/(\d+)$/, 'showUser');
this.route(/^posts\/([a-z0-9-]+)$/, 'showPost');
},
showUser: function(id) {
console.log('用户ID:', parseInt(id, 10));
},
showPost: function(slug) {
console.log('文章别名:', slug);
}
});
三、复杂路由 #
3.1 嵌套路由 #
javascript
var AppRouter = Backbone.Router.extend({
routes: {
'admin': 'adminIndex',
'admin/users': 'adminUsers',
'admin/users/:id': 'adminUserDetail',
'admin/users/:id/edit': 'adminUserEdit',
'admin/posts': 'adminPosts',
'admin/posts/:id': 'adminPostDetail'
}
});
3.2 查询参数 #
javascript
var AppRouter = Backbone.Router.extend({
routes: {
'search': 'search',
'products': 'products'
},
search: function() {
var query = this.getQueryParams();
console.log('搜索参数:', query);
},
products: function() {
var params = this.getQueryParams();
console.log('产品参数:', params);
},
getQueryParams: function() {
var fragment = Backbone.history.getFragment();
var queryString = fragment.split('?')[1];
if (!queryString) return {};
var params = {};
queryString.split('&').forEach(function(pair) {
var parts = pair.split('=');
params[decodeURIComponent(parts[0])] = decodeURIComponent(parts[1] || '');
});
return params;
}
});
3.3 带查询参数的导航 #
javascript
router.navigate('search?q=keyword&page=1', { trigger: true });
router.navigate('products?category=electronics&sort=price', { trigger: true });
四、路由组织 #
4.1 模块化路由 #
javascript
var UserRoutes = {
routes: {
'users': 'listUsers',
'users/:id': 'showUser',
'users/:id/edit': 'editUser'
},
listUsers: function() {
console.log('用户列表');
},
showUser: function(id) {
console.log('用户详情:', id);
},
editUser: function(id) {
console.log('编辑用户:', id);
}
};
var PostRoutes = {
routes: {
'posts': 'listPosts',
'posts/:id': 'showPost'
},
listPosts: function() {
console.log('文章列表');
},
showPost: function(id) {
console.log('文章详情:', id);
}
};
var AppRouter = Backbone.Router.extend({
routes: {}
});
_.extend(AppRouter.prototype, UserRoutes, PostRoutes);
4.2 路由配置对象 #
javascript
var routeConfig = {
home: {
path: '',
action: 'home',
title: '首页'
},
users: {
path: 'users',
action: 'listUsers',
title: '用户列表'
},
userDetail: {
path: 'users/:id',
action: 'showUser',
title: '用户详情'
}
};
var AppRouter = Backbone.Router.extend({
initialize: function() {
var self = this;
_.each(routeConfig, function(config, name) {
self.route(config.path, name, function() {
document.title = config.title;
self[config.action].apply(self, arguments);
});
});
},
home: function() {
console.log('首页');
},
listUsers: function() {
console.log('用户列表');
},
showUser: function(id) {
console.log('用户详情:', id);
}
});
4.3 路由分组 #
javascript
var RouterGroup = function(prefix, routes) {
this.prefix = prefix;
this.routes = routes;
};
RouterGroup.prototype.register = function(router) {
var self = this;
_.each(this.routes, function(handler, path) {
var fullPath = self.prefix + (path ? '/' + path : '');
router.route(fullPath, handler);
});
};
var userRoutes = new RouterGroup('users', {
'': 'listUsers',
':id': 'showUser',
':id/edit': 'editUser'
});
var postRoutes = new RouterGroup('posts', {
'': 'listPosts',
':id': 'showPost'
});
var AppRouter = Backbone.Router.extend({
initialize: function() {
userRoutes.register(this);
postRoutes.register(this);
},
listUsers: function() {},
showUser: function(id) {},
editUser: function(id) {},
listPosts: function() {},
showPost: function(id) {}
});
五、路由守卫 #
5.1 认证守卫 #
javascript
var AuthRouter = Backbone.Router.extend({
routes: {
'login': 'login',
'dashboard': 'dashboard',
'profile': 'profile'
},
execute: function(callback, args, name) {
var publicRoutes = ['login'];
if (publicRoutes.indexOf(name) === -1 && !this.isAuthenticated()) {
this.navigate('login', { trigger: true });
return false;
}
if (callback) callback.apply(this, args);
},
isAuthenticated: function() {
return !!localStorage.getItem('token');
},
login: function() {
console.log('登录页面');
},
dashboard: function() {
console.log('仪表盘');
},
profile: function() {
console.log('个人资料');
}
});
5.2 权限守卫 #
javascript
var PermissionRouter = Backbone.Router.extend({
permissions: {
admin: ['admin', 'adminUsers', 'adminSettings'],
manager: ['dashboard', 'reports'],
user: ['profile', 'settings']
},
execute: function(callback, args, name) {
var userRole = this.getUserRole();
if (!this.hasPermission(name, userRole)) {
this.navigate('forbidden', { trigger: true });
return false;
}
if (callback) callback.apply(this, args);
},
getUserRole: function() {
return localStorage.getItem('role') || 'user';
},
hasPermission: function(route, role) {
var allowedRoutes = this.permissions[role] || [];
return allowedRoutes.indexOf(route) !== -1;
}
});
5.3 确认守卫 #
javascript
var ConfirmRouter = Backbone.Router.extend({
initialize: function() {
this.pendingNavigation = null;
},
execute: function(callback, args, name) {
if (this.hasUnsavedChanges()) {
this.pendingNavigation = { callback: callback, args: args, name: name };
this.showConfirmDialog();
return false;
}
if (callback) callback.apply(this, args);
},
hasUnsavedChanges: function() {
return this.currentView && this.currentView.hasChanges;
},
showConfirmDialog: function() {
if (confirm('有未保存的更改,确定要离开吗?')) {
this.proceedWithNavigation();
} else {
this.pendingNavigation = null;
}
},
proceedWithNavigation: function() {
if (this.pendingNavigation) {
var nav = this.pendingNavigation;
this.pendingNavigation = null;
if (nav.callback) nav.callback.apply(this, nav.args);
}
}
});
六、实用示例 #
6.1 完整应用路由 #
javascript
var AppRouter = Backbone.Router.extend({
routes: {
'': 'home',
'login': 'login',
'register': 'register',
'dashboard': 'dashboard',
'users': 'users',
'users/:id': 'userDetail',
'users/:id/edit': 'userEdit',
'posts': 'posts',
'posts/:id': 'postDetail',
'posts/new': 'postNew',
'settings': 'settings',
'*notFound': 'notFound'
},
initialize: function(options) {
this.app = options.app;
this.currentView = null;
},
showView: function(view) {
if (this.currentView) {
this.currentView.remove();
}
this.currentView = view;
this.app.$main.html(view.render().el);
},
home: function() {
this.showView(new HomeView());
},
login: function() {
this.showView(new LoginView());
},
register: function() {
this.showView(new RegisterView());
},
dashboard: function() {
this.showView(new DashboardView());
},
users: function() {
var collection = new Users();
collection.fetch().then(function() {
this.showView(new UsersView({ collection: collection }));
}.bind(this));
},
userDetail: function(id) {
var model = new User({ id: id });
model.fetch().then(function() {
this.showView(new UserDetailView({ model: model }));
}.bind(this));
},
userEdit: function(id) {
var model = new User({ id: id });
model.fetch().then(function() {
this.showView(new UserEditView({ model: model }));
}.bind(this));
},
posts: function() {
var collection = new Posts();
collection.fetch().then(function() {
this.showView(new PostsView({ collection: collection }));
}.bind(this));
},
postDetail: function(id) {
var model = new Post({ id: id });
model.fetch().then(function() {
this.showView(new PostDetailView({ model: model }));
}.bind(this));
},
postNew: function() {
this.showView(new PostNewView());
},
settings: function() {
this.showView(new SettingsView());
},
notFound: function() {
this.showView(new NotFoundView());
}
});
七、总结 #
7.1 路由配置要点 #
| 要点 | 说明 |
|---|---|
| routes对象 | 定义路由规则 |
| route方法 | 动态添加路由 |
| 参数提取 | :param, *splat |
| 可选参数 | (/optional) |
7.2 最佳实践 #
- 使用语义化的路由路径
- 合理组织路由规则
- 使用路由守卫控制访问
- 处理404页面
- 模块化组织路由
最后更新:2026-03-28