Angular核心-路由和导航
📒博客首页:蔚说的博客 |
---|
🎉欢迎关注🔎点赞👍收藏⭐️留言📝 |
🙏作者水平很有限,如果发现错误,求告知,多谢! |
🌺有问题可私信交流!!! |
(达内教育学习笔记)仅供学习交流 |
@[TOC]Angular核心-路由和导航) |
多页面应用 :一个项目有多个完整的HTML文件,使用超链接跳转–摧毁一颗DOM树,同步请求另一颗,得到之后再重建新的DOM树,不足:DOM树要反复重建,间隔客户端一片空白。
单页面应用 :称为SPA(Single Page Application),整个项目中有且只有一个“完整的”HTML文件,其他的页面都是DIV片段,需要哪个“页面”就将其异步请求下来,“插入”到“完整的”HTML文件中。
==单页面应用的优势:==整个项目中客户端只需要下载一个HTML页面,创建一个完整的DOM树,页面跳转都是一个DIV替换另一个DIV而已—能够实现过场动画
单页面应用不足:不利于SEO优化
Angular中使用单页应用的步骤
(0.)准备整个应用需要的路由组件
ng g component index
ng g component product-list
ng g component product-detail
ng g component user-center
- 定义“路由词典”—[{URL-组件}],[{URL-组件}]
//app.midule.ts 为每个路由组件分配一个路由地址
//声明路由词典-路由地址和路由组件的对应集合
let routes = [
{path:'index',component:IndexComponent},
{path:'plist',component:ProductListComponent},
{path:'pdetail',component:ProductDetailComponent},
{path:'ucenter',component:UserCenterComponent}
]
- 注册“路由词典”
//app.midule.ts
import { RouterModule } from '@angular/router';
imports: [
BrowserModule,
AppRoutingModule,
FormsModule,
HttpClientModule,
RouterModule.forRoot(routes),
//导入路由模块,注册路由词典
- 创建路由组件挂载点—称为“路由出口”
//在app.component.html中
<router-outlet></router-outlet>
- 访问测试
http://localhost:4200/plist
http://localhost:4200/index
注意事项:
- 路由地址不能以"/"开头或者结尾中间可以有“/”,
- 路由词典可以制定一个默认首页地址:{path:“”,component:…}
- 路由词典中每个路由要么指定component(由哪个组件提供内容),要么指定redirectTo(重定向到另一个路由地址)
{path:'', redirectTo: 'index',pathMatch:'full'},
//重定向需要指定“路由地址匹配方式”为“完全匹配”
- 路由词典中可以指定一个匹配任一地址的地址:“**”,注意该地址只能用于整个路由词典的最后一个,在前边就会使后边的地址没有作用。
路由跳转/导航:从一个路由地址跳转到另一个
实现方案:
方式1:使用模板方法
注意:1.可用于任意标签上 2.跳转地址应该以/开头,防止相对方式跳转
实例:
<p>index works!</p>
传统的超链接可以跳转,但是属于DOm树完全重建
<a href="ucenter">进入用户中心</a><br>
使用routerLink就是单页面应用需要在路由地址前加上/不加的话跳转不准
<a routerLink="/ucenter">a标签进入</a><br>
<div routerLink="/ucenter">div进入</div><br>
<button routerLink="/ucenter">按钮进入</button>
方式2:使用脚本方法
注意:Router类是RouterModule提供的一个服务类,声明依赖即可使用
//使用router服务要声明,依赖注入,注入“路由器”服务
constructor(private router:Router) { }
jump(){
//跳转到商品详情页--需要“路由器”服务
this.router.navigateByUrl('/plist')
}
路由传参:实际应用在在商品详情中查看某一个
路由词典:pdetail/:lid,包含可变参数
{path:'pdetail/:lid',component:ProductDetailComponent},
使用按钮进行传参数
<button routerLink="/pdetail/45">按钮进入45</button>
在ngOnInit()函数里边实现读取当前路由地址中的参数:
ngOnInit(): void {
//组件初始化完成,读取路由参数,进而根据此参数做操作
//Observable<Params>对象必须订阅使用subscribe
this.route.params.subscribe((date)=>{
console.log('得到了路由订阅')
console.log(date)
this.productId = date['lid'];
})
}
路由嵌套:
一级路由:
index: 首页
user/center:用户中心
二级路由:
user/center/info:用户中心》我的信息
user/center/avatar:用户中心》更改头像
user/center/security:用户中心》安全管理
路由嵌套修改词典:
let routes = [
{path:'index',component:IndexComponent},
{
path:'user/center',component:UserCenterComponent,
childern:[ //嵌套的二级路由
{path:'info',component:...},
{path:'avatar',component:...},
{path:'security',component:...},
]
}
]
注意:用户中心下的二级路由组件挂载点/路由出口应该放在UserCenter.component.html中
路由守卫
商业项目中,有些路由地址只能在特定的条件下才能访问,例如:
用户中心,只能登陆才能访问,(会话限制)
TMOOC视频播放,只能在学校内播放(客户ip地址限制)
VIP学员视频播放,只能在13:30-22:00时间播放…
Angular提供了“路由守卫(Guard)”来访问路由组件前的检查功能:如果检查通过(return true)就放行,反之不放行。
使用路由守卫的步骤
1.创建路由守卫class
//声明可被注入的
@injectable({providedln:'root'})
export class LoginGuard{
canActivate(){
return true //允许激活
return false //阻止激活
}
}
2.在路由词典中使用路由守卫
{path: '', component:....,canActivate:[LoginGuard]}
实例:
声明路由词典-路由地址和路由组件的对应集合
//声明路由词典-路由地址和路由组件的对应集合
let routes = [
{path:'', redirectTo: 'index',pathMatch:'full'},
{path:'index',component:IndexComponent},
{path:'index',
component:IndexComponent,
canActivate:[TimeGuard],
children :[//嵌套的二级路由
{path:'plist',component:ProductListComponent},
{path:'pdetail/:lid',component:ProductDetailComponent},
{path:'ucenter',component:UserCenterComponent},
]
},
{path:'**',component:NotFoundComponent},
]
imports: [
BrowserModule,
AppRoutingModule,
FormsModule,
HttpClientModule,
RouterModule.forRoot(routes),
//导入路由模块,注册路由词典
],
使用ng g guard time创建路由守卫并编辑
@Injectable({
providedIn: 'root'
})
export class TimeGuard implements CanActivate {
constructor(private router:Router){
}
//如果当前的访问时间是6-23点允许激活
//否则阻止
canActivate(){
console.log('正在进行访问时间检验...')
let hour = new Date().getHours()
console.log(hour)
if(hour >= 10 && hour <= 23){
return true
}else{
console.log('时间超过了不能访问')
alert('时间未到,等am10点后吧')
this.router.navigateByUrl('/index')
return false
}
}
提供路由地址
<a href="/index/ucenter">进入用户中心</a><br>
使用routerLink需要在连接前加上/不加的话跳转不准
<a routerLink="/index/ucenter">a标签进入</a><br>
<div routerLink="/index/ucenter">div进入</div><br>
<button routerLink="/index/ucenter">按钮进入</button>
<hr>
<button (click)="jump()">跳转到商品详情</button>
<button routerLink="/index/pdetail/5">按钮进入5</button>
<button routerLink="/index/pdetail/45">按钮进入45</button>
提供一个占位符,Angular 会根据当前的路由器状态动态填充它。
<router-outlet></router-outlet>