Backbone.js路由基础 #

一、什么是Router #

Router(路由器)是Backbone.js中用于管理URL路由和导航的组件。

1.1 Router的作用 #

text
Router职责
├── URL解析:解析URL并匹配路由规则
├── 导航控制:控制页面导航和跳转
├── 历史管理:管理浏览器历史记录
└── 视图切换:根据路由切换视图

1.2 单页应用与路由 #

text
传统应用:每次URL变化都会刷新页面
单页应用:URL变化时只更新部分内容

Router实现:
├── 监听URL变化
├── 匹配路由规则
├── 执行对应处理函数
└── 更新视图

二、创建Router #

2.1 基本创建方式 #

javascript
var AppRouter = Backbone.Router.extend({
    routes: {
        '': 'home',
        'about': 'about',
        'contact': 'contact'
    },
    
    home: function() {
        console.log('首页');
    },
    
    about: function() {
        console.log('关于页面');
    },
    
    contact: function() {
        console.log('联系页面');
    }
});

var router = new AppRouter();
Backbone.history.start();

2.2 initialize方法 #

javascript
var AppRouter = Backbone.Router.extend({
    initialize: function(options) {
        console.log('路由器已初始化');
        this.options = options;
    }
});

var router = new AppRouter({ debug: true });

2.3 启动历史管理 #

javascript
var router = new AppRouter();

Backbone.history.start({
    pushState: true,
    root: '/app/'
});

三、路由定义 #

3.1 routes对象 #

javascript
var AppRouter = Backbone.Router.extend({
    routes: {
        '': 'home',
        'users': 'listUsers',
        'users/:id': 'showUser',
        'users/:id/edit': 'editUser',
        'search/:query': 'search',
        '*notFound': 'notFound'
    }
});

3.2 路由语法 #

语法 说明 示例
'' 空路径 首页
'path' 静态路径 /about
':param' 动态参数 /users/:id
'*splat' 通配符 /files/*path
'(/optional)' 可选部分 /users(/page/:num)

3.3 动态参数 #

javascript
var AppRouter = Backbone.Router.extend({
    routes: {
        'users/:id': 'showUser',
        'posts/:year/:month': 'showPosts'
    },
    
    showUser: function(id) {
        console.log('用户ID:', id);
    },
    
    showPosts: function(year, month) {
        console.log('文章:', year, month);
    }
});

3.4 通配符 #

javascript
var AppRouter = Backbone.Router.extend({
    routes: {
        'files/*path': 'showFile',
        '*notFound': 'notFound'
    },
    
    showFile: function(path) {
        console.log('文件路径:', path);
    },
    
    notFound: function(path) {
        console.log('未找到:', path);
    }
});

3.5 可选部分 #

javascript
var AppRouter = Backbone.Router.extend({
    routes: {
        'search(/:query)(/p:page)': 'search'
    },
    
    search: function(query, page) {
        query = query || '';
        page = page || 1;
        console.log('搜索:', query, '页码:', page);
    }
});

3.6 正则表达式路由 #

javascript
var AppRouter = Backbone.Router.extend({
    initialize: function() {
        this.route(/^users\/(\d+)$/, 'showUser');
        this.route(/^posts\/(\d{4})-(\d{2})$/, 'showPostsByMonth');
    },
    
    showUser: function(id) {
        console.log('用户ID:', id);
    },
    
    showPostsByMonth: function(year, month) {
        console.log('文章:', year, month);
    }
});

四、路由导航 #

4.1 navigate方法 #

javascript
var router = new AppRouter();

router.navigate('users/1', { trigger: true });

router.navigate('about', { trigger: true, replace: true });

4.2 navigate选项 #

选项 默认值 说明
trigger false 是否触发路由处理函数
replace false 是否替换历史记录

4.3 链接处理 #

html
<a href="#users">用户列表</a>
<a href="#users/1">用户详情</a>
javascript
$(document).on('click', 'a[href^="#"]', function(e) {
    e.preventDefault();
    var href = $(this).attr('href').substring(1);
    router.navigate(href, { trigger: true });
});

五、路由事件 #

5.1 route事件 #

javascript
var router = new AppRouter();

router.on('route', function(name, args) {
    console.log('路由:', name);
    console.log('参数:', args);
});

5.2 特定路由事件 #

javascript
router.on('route:showUser', function(id) {
    console.log('显示用户:', id);
});

router.on('route:listUsers', function() {
    console.log('用户列表');
});

5.3 before事件(自定义) #

javascript
var AppRouter = Backbone.Router.extend({
    before: function(route, params) {
        console.log('路由即将执行:', route);
        if (!this.isAuthenticated()) {
            router.navigate('login', { trigger: true });
            return false;
        }
    },
    
    execute: function(callback, args, name) {
        if (this.before && this.before(name, args) === false) {
            return false;
        }
        if (callback) callback.apply(this, args);
    }
});

六、历史管理 #

6.1 Backbone.history #

javascript
Backbone.history.start({
    pushState: true,
    hashChange: true,
    root: '/app/',
    silent: false
});

6.2 start选项 #

选项 默认值 说明
pushState false 使用HTML5 History API
hashChange true 使用hash变化
root ‘/’ 应用根路径
silent false 是否静默启动

6.3 pushState模式 #

javascript
Backbone.history.start({
    pushState: true,
    root: '/myapp/'
});
html
<a href="/myapp/users">用户</a>

6.4 hash模式 #

javascript
Backbone.history.start({
    hashChange: true
});
html
<a href="#users">用户</a>

6.5 history方法 #

javascript
Backbone.history.navigate('users', { trigger: true });

Backbone.history.loadUrl();

var fragment = Backbone.history.getFragment();

七、实用示例 #

7.1 基础应用路由 #

javascript
var AppRouter = Backbone.Router.extend({
    routes: {
        '': 'home',
        'about': 'about',
        'users': 'users',
        'users/:id': 'userDetail',
        'settings': 'settings',
        '*notFound': 'notFound'
    },
    
    initialize: function(options) {
        this.app = options.app;
    },
    
    home: function() {
        this.app.showView(new HomeView());
    },
    
    about: function() {
        this.app.showView(new AboutView());
    },
    
    users: function() {
        var users = new Users();
        users.fetch().then(function() {
            this.app.showView(new UsersView({ collection: users }));
        }.bind(this));
    },
    
    userDetail: function(id) {
        var user = new User({ id: id });
        user.fetch().then(function() {
            this.app.showView(new UserDetailView({ model: user }));
        }.bind(this));
    },
    
    settings: function() {
        this.app.showView(new SettingsView());
    },
    
    notFound: function() {
        this.app.showView(new NotFoundView());
    }
});

7.2 带认证的路由 #

javascript
var AuthRouter = Backbone.Router.extend({
    routes: {
        'login': 'login',
        'dashboard': 'dashboard',
        'profile': 'profile'
    },
    
    initialize: function() {
        this.on('route', this.checkAuth, this);
    },
    
    checkAuth: function(route) {
        var publicRoutes = ['login'];
        
        if (publicRoutes.indexOf(route) === -1 && !this.isLoggedIn()) {
            this.navigate('login', { trigger: true });
            return false;
        }
    },
    
    isLoggedIn: function() {
        return localStorage.getItem('token') !== null;
    },
    
    login: function() {
        if (this.isLoggedIn()) {
            this.navigate('dashboard', { trigger: true });
            return;
        }
        this.showView(new LoginView());
    },
    
    dashboard: function() {
        this.showView(new DashboardView());
    },
    
    profile: function() {
        this.showView(new ProfileView());
    }
});

7.3 嵌套路由 #

javascript
var AppRouter = Backbone.Router.extend({
    routes: {
        'admin': 'adminIndex',
        'admin/users': 'adminUsers',
        'admin/users/:id': 'adminUserDetail',
        'admin/settings': 'adminSettings'
    },
    
    adminIndex: function() {
        this.showAdminView(new AdminIndexView());
    },
    
    adminUsers: function() {
        this.showAdminView(new AdminUsersView());
    },
    
    adminUserDetail: function(id) {
        this.showAdminView(new AdminUserDetailView({ userId: id }));
    },
    
    adminSettings: function() {
        this.showAdminView(new AdminSettingsView());
    },
    
    showAdminView: function(view) {
        var adminLayout = new AdminLayoutView();
        adminLayout.render();
        adminLayout.showContent(view);
    }
});

八、总结 #

8.1 Router核心方法 #

方法 说明
route(route, name, callback) 添加路由
navigate(fragment, options) 导航到指定路由
execute(callback, args, name) 执行路由处理函数

8.2 History核心方法 #

方法 说明
start(options) 启动历史管理
navigate(fragment, options) 导航
loadUrl() 加载当前URL
getFragment() 获取当前片段

8.3 最佳实践 #

  1. 使用语义化的路由路径
  2. 合理组织路由规则
  3. 使用路由事件进行统一处理
  4. 处理404页面
  5. 考虑认证和权限控制
最后更新:2026-03-28