Angular 基础之——原生路由 VS ui-router

什么是前端路由?

路由的概念来源于服务端,在服务端中路由描述的是 URL 与处理函数之间的映射关系。

Web 前端单页应用 SPA(Single Page Application)中,路由描述的是 URL UI 之间的映射关系,这种映射是单向的,即 URL 变化引起 UI 更新(无需刷新页面)。

如何实现前端路由?

要实现前端路由,需要解决两个核心问题:

  1. 如何改变 URL 却不引起页面刷新?
  2. 如何检测 URL 变化了?

下面分别使用 hash history 两种实现方式回答上面的两个核心问题。

hash 实现

  1. hash 是 URL 中 hash (#) 及后面的那部分,常用作锚点在页面内进行导航,改变 URL 中的 hash 部分不会引起页面刷新
  2. 通过 hashchange 事件监听 URL 的变化,改变 URL 的方式只有这几种:通过浏览器前进后退改变 URL、通过<a>标签改变 URL、通过window.location改变URL,这几种情况改变 URL 都会触发 hashchange 事件

history 实现

  1. history 提供了 pushState 和 replaceState 两个方法,这两个方法改变 URL 的 path 部分不会引起页面刷新
  2. history 提供类似 hashchange 事件的 popstate 事件,但 popstate 事件有些不同:通过浏览器前进后退改变 URL 时会触发 popstate 事件,通过pushState/replaceState<a>标签改变 URL 不会触发 popstate 事件。好在我们可以拦截 pushState/replaceState的调用和<a>标签的点击事件来检测 URL 变化,所以监听 URL 变化可以实现,只是没有 hashchange 那么方便。

原生路由实现

hash

<!DOCTYPE html>
<html lang="en">

<head>
 <meta charset="UTF-8">
 <meta http-equiv="X-UA-Compatible" content="IE=edge">
 <meta name="viewport" content="width=device-width, initial-scale=1.0">
 <title>Native Router Hash</title>
</head>

<body>
 <ul>
   <!-- 定义路由 -->
   <li><a href="#/home">home</a></li>
   <li><a href="#/about">about</a></li>

   <!-- 渲染路由对应的 UI -->
   <div id="routeView"></div>
 </ul>
</body>

<script>
 // 页面加载完不会触发 hashchange,这里主动触发一次 hashchange 事件
 window.addEventListener('DOMContentLoaded', onLoad)
 // 监听路由变化
 window.addEventListener('hashchange', onHashChange)

 // 路由视图
 var routerView = null

 function onLoad() {
   routerView = document.querySelector('#routeView')
   onHashChange()
}

 // 路由变化时,根据路由渲染对应 UI
 function onHashChange() {
   console.log(window.location)
   switch (location.hash) {
     case '#/home':
       routerView.innerHTML = 'Home'
       return
     case '#/about':
       routerView.innerHTML = 'About'
       return
     default:
       return
  }
}
</script>

</html>

history

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Native Router History</title>
</head>

<body>
    <ul>
        <li><a href='/home'>home</a></li>
        <li><a href='/about' class='GGHHJJ'>about</a></li>

        <div id="routeView"></div>
    </ul>
</body>


<script>
    // 页面加载完不会触发 hashchange,这里主动触发一次 hashchange 事件
    window.addEventListener('DOMContentLoaded', onLoad)
    // 监听路由变化
    window.addEventListener('popstate', onPopState)

    // 路由视图
    var routerView = null

    function onLoad() {
        routerView = document.querySelector('#routeView')
        onPopState()

        // 拦截 <a> 标签点击事件默认行为, 点击时使用 pushState 修改 URL并更新手动更新 UI,从而实现点击链接更新 URL 和 UI 的效果。
        var linkList = document.querySelectorAll('a[href]')
        linkList.forEach(el => el.addEventListener('click', function (e) {
            e.preventDefault()
            history.pushState(null, '', el.getAttribute('href'))
            onPopState()
        }))
    }

    // 路由变化时,根据路由渲染对应 UI
    function onPopState() {
        switch (location.pathname) {
            case '/home':
                routerView.innerHTML = 'Home'
                return
            case '/about':
                routerView.innerHTML = 'About'
                return
            default:
                return
        }
    }
</script>

</html>

angular UI-router

// 所需插件版本
"@uirouter/angular": "^9.1.0",
"@uirouter/core": "^6.0.8",
"@uirouter/rx": "^1.0.0",

app.module.ts

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent, Page1, Page3, Page2 } from './app.component';// 导入组件模块
import { UIRouterModule } from "@uirouter/angular";// 导入 uirouter UIRouterModule 方法
import { platformBrowserDynamic } from "@angular/platform-browser-dynamic";

// UI router state
// 
const Page1State = { name: "Page1", url: "/Page1", component: Page1 };
const Page2State = { name: "Page2", url: "/Page2", component: Page2 };
const Page3State = { name: "Page3", url: "/Page3", component: Page3 };



// imports: [ BrowserModule, UIRouterModule.forRoot({ ...
// 允许您应用的模块使用来自另一个模块的代码。在此示例中,UIRouterModule.forRoot导入 UI-Router 模块,并注册列出的状态。
// declarations: [ Page1, Page2, Page3 ]
// 声明根模块中使用的所有组件。
// bootstrap: [ AppComponent ]
// 告诉 Angular 引导App组件作为应用程序的根。

@NgModule({
  imports: [
    BrowserModule,
    UIRouterModule.forRoot({ states: [Page1State, Page2State, Page3State], useHash: true })
  ],
  declarations: [
    AppComponent,
    Page1, 
    Page2,
    Page3
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }

platformBrowserDynamic().bootstrapModule(AppModule).then(ref => {
  // 确保 Angular 在热重载时自行销毁。
  if (window['ngRef']) {
    window['ngRef'].destroy();
  }
  window['ngRef'] = ref;
}).catch(err => console.error(err));

app.component.html


//  每个标记都包含一个uiSref指令。uiSref指令是链接,类似于锚标记的href. 不是像 a href那样链接到 URL,而是uiSref链接到状态。
// 单击时,链接状态被激活。该指令会根据您所在州的 urluiSref自动为您构建一个href属性 ( )。<a href=...></a>
// 当uiSref链接到的状态为活动时,uiSrefActive会将activeCSS 类添加到链接
<a uiSref="Page1" uiSrefActive="active">Page-1</a>
<a uiSref="Page2" uiSrefActive="active">Page-2</a>
<a uiSref="Page3" uiSrefActive="active">Page-3</a>

// 此视口将填充当前活动状态的组件
<ui-view></ui-view>

app.component.ts

import { Component } from '@angular/core';

// root app
@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  title = 'uiRouterDemo';
}
// component 1
@Component({
  template: "<h3>Page-1</h3>"
})
export class Page1 {}

// component 2 
@Component({
  template: "<h3>Page-2</h3>"
})
export class Page2 {}

//component 3
@Component({
  template: "<h3>Page-3</h3>"
})
export class Page3 {}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
AngularJS `ui-view` 的使用通常涉及以下几个步骤: 1. 安装 AngularJS 和 AngularUI RouterAngularUI Router 是一个用于 AngularJS 的第三方路由模块,可以实现多视图和嵌套路由等功能。 2. 在 HTML 中定义 `ui-view` 指令,用于展示视图。可以定义一个或多个 `ui-view`,每个指令可以使用一个名字来标识。 3. 在 JavaScript 中配置路由,并指定与视图相关的模板和控制器。通常使用 `$stateProvider` 和 `$urlRouterProvider` 服务来配置路由。 下面是一个简单的示例,演示了如何使用 `ui-view` 展示两个页面: ```html <!DOCTYPE html> <html ng-app="myApp"> <head> <meta charset="utf-8"> <title>AngularJS UI-Router Demo</title> <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.8.2/angular.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-router/1.0.29/angular-ui-router.min.js"></script> <script> // 创建 AngularJS 应用程序 var app = angular.module('myApp', ['ui.router']); // 配置路由 app.config(function($stateProvider, $urlRouterProvider) { $stateProvider .state('home', { url: '/', templateUrl: 'home.html', controller: 'HomeController' }) .state('about', { url: '/about', templateUrl: 'about.html', controller: 'AboutController' }); $urlRouterProvider.otherwise('/'); }); // 控制器定义 app.controller('HomeController', function($scope) { $scope.message = 'Welcome to the homepage!'; }); app.controller('AboutController', function($scope) { $scope.message = 'Learn more about us!'; }); </script> </head> <body> <h1>AngularJS UI-Router Demo</h1> <nav> <a ui-sref="home">Home</a> <a ui-sref="about">About</a> </nav> <div ui-view></div> </body> </html> ``` 在上面的示例中,我们定义了两个路由:`home` 和 `about`。每个路由都指定了一个与之对应的模板和控制器。在 HTML 中,我们使用 `ui-sref` 指令来指定路由,并使用 `ui-view` 指令来展示视图。在这种情况下,我们只有一个 `ui-view`,因此没有必要给它指定任何名字。 当用户点击导航链接时,将会触发路由,对应的视图将会展示在 `ui-view` 中。在这个示例中,我们在 `HomeController` 和 `AboutController` 中定义了一些文本信息,用于展示在对应的视图中。 注意,使用 `ui-sref` 指令时,需要将路由名称作为参数传递给指令。这个名称应该与路由配置中的名称匹配。 这只是一个简单示例,实际应用中可能还需要更多的路由和视图。掌握了 `ui-view` 的基本使用方法之后,你可以继续学习 AngularUI Router 的更多功能,例如嵌套视图、路由参数等等。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值