Angular入门及学习笔记

原创
2020/05/06 20:21
阅读数 144

 

Angular

谷歌开源的JavaScript库,性能比之前最先的版本提升很多,采用Typescript进行,以及新的模式进行开发,所以从第二版本开始,突然大幅下降人数。

技术:typescript的基本使用,es6

TypescriptJavaScript超集,JavaScript内容和es6都可以直接在typescript中使用。

Typescript的代码依然要编译成纯JavaScripttypescript编译工具可以运行在任何的服务器和任何系统上。Typescript开源

Typescript:

1、非常包容,JavaScript

2、定义简单到复杂的一切类型。

3typescript如果报错,依然可以生成JavaScript文件

4typescript拥有活跃的社区。

Typscript缺点:

  1. 学习成本高
  2. 短期项目,简单的项目,效率低下。
  3. 跟其他库的兼容性不高。

安装typescript

cnpm install -g typescript

创建后缀为。ts的文件,最后需要通过编译转成js

TS文件编译成js

tsc index.ts

安装Angular-cli

cnpm install -g @angular/cli

创建项目

ng new angularApp --skip-install

安装模块

npm install

启动开发服务命令

Npm start

启动时候打开浏览器

ng serve --open

创建组件命令

ng g component  component/news

组件使用:

<app-news></app-news>

Typescript数据类型

原始数据类型:布尔,数值,字符串,nullundefined;

布尔类型定义:注意直接调用Boolean是可以的

let isDone:boolean = true;
isDone = false;
let isCheck:boolean = Boolean(1)

错误方式:因为new Boolean返回的是1个对象类型

let isCheck:boolean = new Boolean(1)

数值类型定义

let num:number = 1;
let num16:number = 0xf00a;
let notNum:number = NaN;
let infNum:number = Infinity;

字符串类型定义

let username:string = 'laochen';
let age:number = 30;
let juzi:string = `我的年龄是${age}`;

空值:大部分情况下用于定义函数没有返回值,一般不用于定义变量,因为一旦变量定义为void类型,那么就只能赋值undfined,null;

//空值
function hello():void{
    console.log('helloworld')
}

let unable:void = undefined;
unable = null;

Nullundefined定义

//null和undefined类型,意义不大
let a:undefined = undefined;
a = null;

let b:null = null;
b = undefined;

注意:nullundefined是所有类型的子类型,void类型是不能赋值给其他类型的,虽然它也只有undefinednull,例如

let username:string = 'laochen';
username = undefined;
let abc:undefined = undefined;
let cba:void = undefined;
username = abc;
//username = cba;//这是不允许,因为cba是void类型
let age:number = 30;

任意值类型

任意值类型(any)用来表示允许任意值类型赋值。

//任意值类型
let admin:any = 'adbc'
admin = 123;

//任意值类型允许访问他任意的属性
let anything:any = 'hello';
console.log(anything.myname);

未申明类型的变量

let something1;
//something1在声明时候未定义类型,也没有赋值,就会被定义为任意值类型
something1 = 'abc';
something1 = 123;

类型推断

//something2在声明的时候虽然未定义类型,但是由于赋值为字符串,typescript有类型推断规则,会将赋值的类型定义成变量的类型
let something2 = 'abc';
//something2 = 123;//会报错

联合类型:表示取值可以取多个类型。

let cat:string|number;
cat = '小猫咪';
cat = 1;

let cat1:string|number = '小猫咪';

Typescript接口

什么是接口?行为的抽象。具体行动需要由类去实现(接口抽象出来的内容)。

相当于定义类的描述。

定义:

interface Person{
    name:string;
    age:number;
}

let tom:Person = {
    name:"tom",
    age:16,
}
//约束TOM这个对象,必须和接口一致属性。
//一般接口的首字母大写。
//用接口定义的对象,属性不能多写,也不能少写

接口可选属性:该属性可写,可不写,但不能多写属性,加?即可

//接口属性可选
interface Student{
    name:string;
    age?:number;
}

let s1:Student = {
    name:"小明",
    age:16,
}

接口可定义任意的属性

//任意属性
interface Teacher{
    name:string;
    age?:number;
    [propName:string]:any;
}

let t1:Teacher={
    name:"老王",
    age:35,
    school:'清华'
}

只读属性,readonly

interface Cat{
    //只读属性,只能进行1次赋值,后面不可以在修改,但是可以获取
    readonly name:string;
    color:string;
    age:number;
}

let c1:Cat = {
    name:'波斯猫',
    color:"白色",
    age:10
}

//c1.name = '中华猫'; //会报错,因为c1.name是只读属性

Typescript函数

typescript会对函数的输入和输出有约束,

输入和输出会定义类型,参数传入(参数定义类型),返回值(定义类型)

//typescript会对函数的输入和输出有约束,
//输入和输出会定义类型,参数传入(参数定义类型),返回值(定义类型)

function sum1(x:number,y:number) :number{
    return x+y;
}

let result:number = sum1(3,4);

函数表达式写法

//函数表达式写法

let sum2 = function(x:number,y:number) :number{
    return x+y;
}
//这种写法,实质上仅将右侧匿名函数进行了类型的定义。对左边sum2这个变量没有实质的定义;

let sum3:(x:number,y:number) => number = function(x:number,y:number) :number{
    return x+y;
}

可选参数,加?

//可选参数
function sumName(firstname:string,lastname?:string):string{
    return firstname+lastname;
}
sumName('lao',"chen");
sumName('lao');
//注意:可选参数必须放置到必须参数的后面,可选参数后面不允许放置必须要的参数
//不允许
// function sumName2(lastname?:string,firstname:string,):string{
//     return firstname+lastname;
// }

参数默认值

//默认参数
function sumName3(firstname:string='chen',lastname:string='guan'):string{
    return firstname+lastname;
}

剩余参数

必要参数,默认参数和可选参数有个共同点:它们表示某一个参数。 有时,你想同时操作多个参数,或者你并不知道会有多少参数传递进来。 在JavaScript里,你可以使用 arguments来访问所有传入的参数。
剩余参数会被当做个数不限的可选参数。 可以一个都没有,同样也可以有任意个。 编译器创建参数数组,名字是你在省略号( ...)后面给定的名字,你可以在函数体内使用这个数组。
//剩余参数
//ES6正常模式
function fnpush(...items){

}

function fnpush1(...items:any[]):string{
    return 'abc';
}

重载

//重载
//重载允许1个函数,接收不同数量或者类型的参数
function setAbc(x:number|string):number|string{
    return x;
}

function fnAbc(x:boolean):boolean;
function fnAbc(x:number):number;
function fnAbc(x:string):string;
function fnAbc(x:any):any{
    if(typeof x==='number'){
        return x;
    }else{
        return x
    }
}

fnAbc('1')
fnAbc(false)

//定义静态方法
class Animal{
    static isAnimal(a){
        return  a instanceof Animal;
    }
}


let dog = new Animal();
Animal.isAnimal(dog);

//typescript静态属性
class Dog{
    static age =20;
}

console.log(Dog.age)

//类属性
class Abc{
    a = 1;
    b = 3;
    private c = 4;
    constructor(){
        this.a = 1;
        this.b = 2;
        this.c = 3;
    }
}

//属性可以有3种访问的修饰符进行修饰,public/private/protect
//public,任何地方都可以访问,默认所有的属性都是public
//private,私有的,只能在类的内容访问,不能类外面访问
//protected,受保护的,protect在子类里可以访问,private是不允许的


class Banana{
    private name;
    public constructor(name){
        this.name = name;
    }
}

let aa = new Banana('海南香蕉');
//console.log(aa.name)//不能获取,name是私有属性
//aa.name = '巴黎香蕉' //不能访问,name是私有属性


class Apple{
    protected name;
    public constructor(name){
        this.name = name
    }
}

//protect在子类中允许访问。
class BigApple extends Apple{
    private constructor(name){
        super(name)
        console.log(this.name)
    }
}
//如果构造函数式私有的将不能实例化
//let bb = new BigApple('aaaa');

//抽象类,抽象类不允许实例化,一般用于继承实现。
abstract class PinkPig{
    public name;
    constructor(name){
        this.name = name
    }
    //只定义,不实现
    public abstract sayHi();
}

class SmallPinkPig extends PinkPig{
    sayHi(){
        console.log("helloworld")
    }
}

Angular_css

注意:Componet.css仅用于组件,src根目录下的style.css全局的样式

Angular模板语法

MVVM设计模式起源于MVC

  1. >model:数据(模型)/状态

V->view:视图

C->控制器:交互修改数据的方式

MVVC

M->model

V->view

VM -> 对数据和视图的双向绑定,只要修改数据,vm(框架)就会自动改变视图,视图的交互改变了数据。

Angular插值

语法:{{ ...变量和表达式}}

应用:应用于html内容里,也可以应用于property

<h1 [innerHtml]="htmlStr"></h1>

Angular 样式

定义的class三种方式,跟VUE一致,会自动的将变量和原有的HTMLCLASS相加

<!-- 定义变量的方式 -->
<h1 class="abc" class="{{classStr}}">class1</h1>
<h1 class="abc" [class]="classStr">class2</h1>
<h1 [attr.class]="classStr">class3</h1>

Class变量类型

<!-- 变量类型 -->
<!-- 字符串模式 -->
<h1 [class]="classStr">class4</h1>
<h1 class="a" [class]="'str abc'">class4</h1>
<!-- 对象模式 -->
<h1 [class]="classObj">class5</h1>
<h1 [class]="{bgBlue:isShow}">class6</h1>
<!-- 数组模式 -->
<h1 [class]="['bgBlue','active','abc']">class7</h1>
<h1 [class]="classArr"></h1>

Style

<!-- style -->
<!-- style表达式类型 -->
<!-- 字符串变量 -->
<h1 [style]="styleStr"></h1>
<!-- 对象模式 -->
<h1 [style]="styleObj"></h1>
<!-- 橙色 -->
<h1 [style.height]="styleObj.width">h</h1>
<h1 [style.width]="colorAbc"></h1>
<h1 [style.width.px]="widthNum"></h1>

事件

<!-- 
  绑定事件:
  由等号左侧写小括号加上事件名称,右边写调用的事件函数
 -->
<button (click)="changeColor()">改变颜色</button>

<button (click)="changeButton($event)">改变颜色</button>

上面用到的练习代码

isShow = true;
  classArr = ['abc','cba','aaa'];
  styleStr = "background:skyblue;width:400px;height:400px;";
  styleObj = {
    background:"pink",
    width:'100px',
    height:"100px"
  };
  colorAbc='100px';
  widthNum = 200;
  changeColor(){
    this.styleObj = {
      background:"purple",
      width:'200px',
      height:"300px"
    };
  }
  changeButton(event){
    console.log(event)
    event.target.style.background = 'green'
  }

条件渲染

<!-- 条件渲染 -->
<!-- person如果是广东人,就显示广东人的疫情信息 -->
<div *ngIf="person=='广东人'">
  广东:1000人
</div>

<div *ngIf="person=='湖北人'">
  湖北:40000人
</div>

<button (click)="togglePerson()">切换身份</button>

<h1>style的条件渲染</h1>
<!-- 
  这里使用的条件渲染,会移除出Document,添加进DOM都会消耗性能。
 -->
<!-- 使用STYLE进行条件渲染,如果需要频繁切换内容,那么需要style完成条件渲染-->
<div [style.display]="person=='广东人'?'block':'none'">
  广东:1000人
</div>

<div [style.display]="person=='湖北人'?'block':'none'">
  湖北:40000人
</div>



<!-- 条件渲染,匹配多种情况 -->
<div [ngSwitch]="homeState">
  <div *ngSwitchCase="'睡觉'">卧室</div>
  <div *ngSwitchCase="'看电视'">客厅</div>
  <div *ngSwitchCase="'吃饭'">餐厅</div>
  <div *ngSwitchCase="'发呆'">阳台</div>
  <div *ngSwitchDefault>厕所</div>
</div>

<!-- 条件渲染,匹配多种情况 -->
<div [ngSwitch]="orderState">
  <div *ngSwitchCase="1">待付款</div>
  <div *ngSwitchCase="2">已付款</div>
  <div *ngSwitchCase="3">发货</div>
  <div *ngSwitchCase="4">已收货</div>
  <div *ngSwitchDefault>丢失</div>
</div>

循环渲染

<!-- 列表循环 -->
<ul>
  <li *ngFor="let item of arr">{{item}}</li>

</ul>

<!-- 列表循环获取索引值 -->
<ul>
  <li *ngFor="let item of arr;let i=index">索引值:{{i}};内容:{{item}}</li>
</ul>

<!-- 将列表的内容传入事件 -->
<ul>
  <li *ngFor="let item of arr;let i=index" (click)="choosePerson(item,i)">索引值:{{i}};内容:{{item}}</li>
</ul>

<!-- 循环复杂数组 -->
<ul>
  <li *ngFor="let item of students;let key=index">{{key}}-{{item.name}}的爱好是{{item.hobby}}</li>
</ul>

Angular数据双向绑定

导入模块至app.module.ts

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
//导入form模块
import { FormsModule} from '@angular/forms'

import { AppComponent } from './app.component';
import { NewsComponent } from './views/news/news.component';

@NgModule({
  declarations: [
    AppComponent,
    NewsComponent
  ],
//导入
  imports: [
    BrowserModule,
    FormsModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

表单的数据绑定

<input type="text" [(ngModel)]="username">

设置临时变量绑定DOM对象

<!-- 表单数据获取 -->
<div>
  <label for="">用户名</label>
  <input #input1 type="text" >
</div>

<div>
  <label for="">密码</label>
  <input #input2 type="text" >
</div>

<button (click)="getContent(input1.value,input2.value)">获取账号密码</button>

NgForm获取整个表单的数据,NgForm只能用在表单内

<form action="" #formobj>
  <input type="text" [(ngModel)]="username" name="username" >
  <input type="text" [(ngModel)]="password" name="password" >

  <button (click)='eventFn(formobj)'>按钮</button>
</form>

管道(跟vue过滤器类似)

将对象转换成json格式显示
<h1>{{student | json}}</h1>
将时间转化yy/MM/dd格式
<h1>显示时间:{{time | date:"yy/MM/dd"}}</h1>
转全大写
<h1>用户名:  {{username | uppercase}}   </h1>
//管道可以转换多次
<h1>{{'abcdefg'|uppercase|lowercase}}</h1>

自定义管道

创建自定义的管道文件

ng g pipe filter/lcUppercase
import { Pipe, PipeTransform } from '@angular/core';

// @Pipe({
//   name: 'lcUppercase'
// })
// export class LcUppercasePipe implements PipeTransform {

//   transform(value:string,...args:string[]):string {
//     if(value=="老陈"){
//       return "大帅哥老陈"
//     }
//     return value ;
//   }

// }
@Pipe({
  name: 'lcUppercase'
})
export class LcUppercasePipe implements PipeTransform {

  transform(value:string,...args:string[]):string {
    console.log(args)
    return '¥'+value+args[0];
  }

}

模板

注意:msg是模板变量,lcUppercase是转换函数,:后面是参数

<h1>{{msg|lcUppercase:'元'}}</h1>

//msg=100
//根据上面的自定义管道得到的结果是 ¥100元

父组件传值给子组件

//在父组件(html)中传参
<app-child [item]="sendchildMsg"></app-child>
//父组件中的(ts)值
sendchildMsg ="这是给子元素的数据,希望在子组件中显示";


//子组件导入Input
import {Input} from '@angular/core';

export class ChildComponent implements OnInit {
//@input的作用是定义模块输入,是用来让父级组件向子组件传递内容。
  @Input() item;
}

//子组件(html)
<h1>{{item}}</h1>
//显示的结果是:这是给子元素的数据,希望在子组件中显示

子组件传数据给父组件

//子组件模板(.html)
<button (click)="sendMsg()">发送消息给父组件</button>

//子组件逻辑(.ts)
//Output用于把一个类字段标记为输出属性,并提供配置元数据。 凡是绑定到输出属性上的 DOM 属性,Angular 在变更检测期间都会自动进行更新。
//angular提供了EventEmitter用来触发自定义事件。子指令创建一个 EventEmitter 实例,并将其作为输出属性导出。子指令调用已创建的 EventEmitter 实例中的 emit(payload)方法来触发一个事件,父指令通过事件绑定(eventName)的方式监听该事件,并通过 $event 对象来获取payload对象。
//导入
import {Output,EventEmitter } from '@angular/core';

export class ChildComponent implements OnInit {
  //实例化
  @Output() childMsg=new EventEmitter()
  //自定义事件
  sendMsg(){
    this.childMsg.emit({msg:"我子组件,这是我发给父组件的消息"})
  }
}


//父组件模板
<h1>子组件发来信息:{{getChildMsg}}</h1>
//监听事件,childMsg自定义
<app-child (childMsg)="getEvent($event)"></app-child>

//父组件逻辑
export class AppComponent {
  getChildMsg="";
  getEvent(event){
    console.log(event)
    this.getChildMsg = event.msg
  }
}

生命周期函数

 constructor(){
    console.log("组件构造函数调用")
  }
  
  ngOnChanges(){
    console.log("数据发生变化之时就会调用此函数ngOnChanges")
  }

  ngOnInit(){
    console.log("第一次显示数据绑定和指令输入属性之后,就会调用,只调用一次")
  }

  ngDoCheck(){
    console.log('在ngOnChanges和ngOnInit发生之后,会进行一次检测')
  }

  ngAfterContentInit(){
    console.log('数据内容渲染到视图上之后')
  }

  ngAfterContentChecked(){
    console.log('数据内容渲染到视图检测之后')
  }

  ngAfterViewInit(){
    console.log('完成组件和子组件初始化')
  }

  ngAfterViewChecked(){
    console.log('完成组件和子组件初始化检测后')
  }


  ngOnDestory(){
    console.log("销毁组件")
  }

自定义指令

创建指令文件:

ng g directive directive/lcstyle

设置指令内容和功能

//父组件
<h1 [appLcstyle]="'abc'"></h1>


//ElementRef 顾名思义是元素参阅。
其实在实际应用中就是获取视图层的dom元素,借助Augular提供的依赖注入机制,轻松的访问到dom元素。
//子组件Directive
import { Directive,Input,ElementRef } from '@angular/core';
//自定义指令
@Directive({
  selector: '[appLcstyle]'
})
export class LcstyleDirective {

  @Input() appLcstyle;
  constructor(public ref:ElementRef) { 
    console.log('ref')
//会输出dom元素
  }
//生命周期函数
  ngOnChanges(){
    //console.log(this.appLcstyle)
    //console.log(this.ref)
    this.ref.nativeElement.className = this.appLcstyle;
    this.ref.nativeElement.innerHTML = this.appLcstyle;
    this.ref.nativeElement.addEventListener("click",()=>{
      this.ref.nativeElement.style.background="pink"
    })
  }

}

自定义服务:很多组件需要共用的功能抽象出来(类和函数)

1、创建服务文件

ng g service service/stocklist

服务

import { Injectable } from '@angular/core';
import axios from 'axios'

@Injectable({
  providedIn: 'root'
})
export class StockListService {

  constructor() { }
  async getAllStocks(){
    let httpUrl = 'http://localhost:8080/stocklist';
    let result = await axios.get(httpUrl);
    return result.data.data;
  }
  async superStocks(){
    let httpUrl = 'http://localhost:8080/superStock';
    let result = await axios.get(httpUrl);
    return result.data.data;
  }
}

2、导入服务到项目中

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import { AppComponent } from './app.component';
import { LcstyleDirective } from './directive/lcstyle.directive';
//将服务导入到项目中
import { StockListService } from './service/stock-list.service'

@NgModule({
  declarations: [
    AppComponent,
    LcstyleDirective
  ],
  imports: [
    BrowserModule
  ],
  //导入服务
  providers: [
    StockListService
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }

使用服务获取数据

import { Component } from '@angular/core';
import axios from 'axios';
import {StockListService} from './service/stock-list.service';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  title = 'angularapp';
  stockList = []
  superStocks = []
  //注入服务
  constructor( public stockSer:StockListService ){
    // let httpUrl = 'http://localhost:8080/stocklist';
    // axios.get(httpUrl).then((res)=>{
    //   console.log(res.data)
    //   this.stockList = res.data.data.slice(0,10)
    //   console.log(this.stockList)
    // })
    stockSer.superStocks().then((res)=>{
      this.superStocks = res.slice(0,10)
    })
    
  }
  async stockFn(){
    console.log(123)
    let allStocks = await this.stockSer.getAllStocks()
    this.stockList = allStocks.slice(0,10)
  }
}

页面

<button (click)="stockFn()">获取10股票列表</button>
<h1>预估今日涨停的十只股票</h1>
<div *ngFor="let item of superStocks">
  <h1>股票名称:{{item.stockName}}</h1>
  <h2>股票代码:{{item.stockCode}}</h2>
  <div class="img">
    <img src="{{item.dailyChart}}" alt="">
    <img src="{{item.hourlyChart}}" alt="">
  </div>
</div>

<h1>普通股票</h1>

<div *ngFor="let item of stockList">
  <h1>股票名称:{{item.stockName}}</h1>
  <h2>股票代码:{{item.stockCode}}</h2>
  <div class="img">
    <img src="{{item.dailyChart}}" alt="">
    <img src="{{item.hourlyChart}}" alt="">
  </div>
</div>

路由配置

import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import {IndexComponent} from './view/index/index.component';
import {AboutComponent} from './view/about/about.component';
import {NewsComponent} from './view/news/news.component'

//配置路由对象
const routes: Routes = [
  {
    //不需要加/
    path:"",
    component:IndexComponent
  },
  {
    path:'about',
    component:AboutComponent
  },
  {
    path:"news",
    component:NewsComponent
  }

];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule { }

HTML模板

<!-- 根据路径的变化,显示不同组件 -->

<style>
  div>span{
    margin: 20px;
    padding: 5px 10px;
    background-color: skyblue;
  }
</style>

<div>
  <span [routerLink]="['/']" routerLinkActive="router-link-active" >首页</span>
  <span [routerLink]="['/about']" routerLinkActive="router-link-active" >about</span>
  <span [routerLink]="['/news']" routerLinkActive="router-link-active" >news</span>
</div>

<router-outlet></router-outlet>

动态路由

{
    //动态路由
    path:"news/:id",
    component:NewsComponent
  },

获取动态路由的参数

import { Component, OnInit } from '@angular/core';
//导入route
import {ActivatedRoute} from '@angular/router'

@Component({
  selector: 'app-news',
  templateUrl: './news.component.html',
  styleUrls: ['./news.component.less']
})
export class NewsComponent implements OnInit {
  title = ""
  //注入route
  constructor(public route:ActivatedRoute) {
    //http://localhost:4200/news/123?search=meinv#abc
    //console.log(this)
    

  }

  ngOnInit(): void {
    //console.log(this)
    //let params = this.route.params;
    //console.log(params.value.id);
  }
  goParams(){
//使用参数
    this.route.params.subscribe((params)=>{
      console.log(params)
      this.title = params.id;
    })
  }
}

子路由

{
    path:'admin',
    component:AdminComponent,
    children:[
      {
        path:'user',
        component:UserComponent
      },
      {
        path:'product',
        component:ProductComponent
      }
    ]
  },

HTML模板设置

<p>admin works!</p>
<style>
    .admin{
        display: flex;
        height: 600px;
    }
    .admin .left{
        width: 200px;
        background: skyblue;
    }
    .admin .main{
        flex:1;
        background: lavenderblush;
    }
</style>
<div class="admin">
    <div class="left">
        这是侧边栏
        <div [routerLink]="['/admin/user']" routerLinkActive="router-link-active" >user</div>
        <div [routerLink]="['/admin/product']" routerLinkActive="router-link-active" >product</div>
    </div>
    <div class="main">
        <router-outlet></router-outlet>
    </div>
</div>

编程式导航,JS如何控制路由的跳转

1/依赖注入router

import { Component, OnInit } from '@angular/core';
//导入route,router
import {ActivatedRoute,Router} from '@angular/router'

@Component({
  selector: 'app-news',
  templateUrl: './news.component.html',
  styleUrls: ['./news.component.less']
})
export class NewsComponent implements OnInit {
  title = ""
  //注入route,router
  constructor(public route:ActivatedRoute,public router:Router) {
    //http://localhost:4200/news/123?search=meinv#abc
    console.log(this)
    this.route.data.subscribe((data)=>{
      console.log(data)
      this.title = data.msg
    })

  }

  ngOnInit(): void {
    //console.log(this)
    //let params = this.route.params;
    //console.log(params.value.id);
  }
  goParams(){
    this.route.params.subscribe((params)=>{
      console.log(params)
      this.title = params.id;
    })
    
  }

  goHome(){
    //第一个参数是传入数组(路径的数组)
    this.router.navigate([''],{
      queryParams:{
        usernam:"admin"
      },
      fragment:"abc",
      replaceUrl:true
    })
  }
}

 

//第一个参数是传入数组(路径的数组),自动拼接成完整的路径
this.router.navigate([''],{
//拼接参数
      queryParams:{
        usernam:"admin"
      },
      fragment:"abc",//传hash值
//是不是要替换当前的页面
      replaceUrl:true
    })

 

展开阅读全文
加载中
点击引领话题📣 发布并加入讨论🔥
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部