Google开发的的一款开源的web前端框架
基于TypeScript
,与react
,vue
相比较它更适用于中大型企业级项目。
学习路径
HTML
,CSS
,JavaScript
Es6
Typescript
1.1 安装前准备工作
安装node.js (稳定版本最好)
node.js是什么
安装教程
问题
终端中查看版本
node -v
npm -v
安装cnpm
终端中下载
npm install -g cnpm -- registry=https://registry.npm.taobao.org
cnpm -v
使用npm/cnpm命令安装 Angular/cli(只需安装一次)
终端中下载
npm install -g @angular/cli
cnpm install -g @angular/cli
面试题: 可维护性,可修改性,可拓展性
数据绑定,指令系统,组件式编程,路由和导航,
状态保持,第三方组件库
打开命令行工具找到要创建项目的目录
创建项目
ng new +项目名称
ng serve --open运行项目
注意
右键终端,以管理员模式打开
ng v
npm uninstall -g @angular/cli
npm install -g @angular-cli
cd angular
ng new project1
ng serve --open
在过程中有不断地改变文件,目录的权限
在ng new project1
过程其实是npm i
过程,不断给项目添加依赖,过程较慢,用ctrl+c
中止,用cnpm install
较快
结果,成功运行
将所创建的Angular程序拖拽到VScode里
未解决问题
转为用离线安装.vsix插件
的方式
VScode
选项下搜索插件VScode
的bin目录
下shift+鼠标右键
选择在此处打开Powershell窗口
.\code --install-extension 插件名
,successfully即成功e2e
node——modules
package.json
定义的模块通过npm/cnpm install
下载到该目录下 作用
app
存放组件,根模块
根模块
app.module.ts
根组件
app.component.html
app.component.scss
app.component.ts
assets
静态资源文件
browserlist
favicon.ico
index.html
main.ts
polyfills.ts
styles.scss
全局的CSS文件
ng new project1
选择的预编译方式作为后缀的文件 test.ts
其他的基本上是配置文件
创建组件/服务 :
ng g
http://cli.angular.io/
创建组件
ng g component components/news
使用组件
app.modules.ts
中
import { NewsComponent } from './components/news/news.component';
NewsComponent
<组件名称>组件名称>
ctrl+s
就可直接刷新页面ng serve --open
在.ts文件中public定义数据 (默认也是public)
public title="我是前端"
msg="我是msg"
username:string='张三'
number:any=123456
//推荐使用
public student:string='王麻子'
在.html文件中绑定数据
<h1>{{title}}h1>
<h2>{{msg}}h2>
声明属性的几种方式
声明对象
public userinfo:object={,,}
error TS2339: Property 'age' does not exist on type 'object'问题
public userinfo:any={,,}
this.msg=''
;console.log(this.msg)
this.msg="改变值"
静态属性
<div title="我是一个div">
鼠标瞄上去会显示“我是一个div”
div>
动态属性
<div [title]="student">
李华(鼠标瞄上去会显示“这是一个学生”)
div>
<div>{{content}}div>
<div>解析前-->解析后div>
<span [innerHTML]="content" class="red">span>
1+2={{1+2}}
简单数组
in .ts
public arr=['1','2','3']
in .html
<ul>
<li *ngFor="let item of arr">
{{item}}
li>
ul>
Property ‘item’ does not exist on type ‘HomeComponent’.问题未解决
对象数组
in .ts
public userlist:any[]=[{
name:'zara',
time:1
},{
name:'marry',
time:4
}];
in .html
复杂数组
-
{{item.name}}--{{item.time}}
为什么这个复杂的可以输出
嵌套数组
in .ts
public car:any[]=[{
p:'宝马',
list:[{
price:100,
n:'w'
}]},{
p:'奥迪',
list:[{
price:200,
n:'a'
}]
}]
in .html
<ul>
<li *ngFor="let m of car">
<h2>{{m.p}}h2>
<ol>
<li *ngFor="let i of m.list">
{{i.price}}--{{i.n}}
li>
ol>
li>
为什么可以得到嵌套数据
ul>
引入本地图片
属于静态资源,存入assets
在src中存放路径
<img src="assets/picture/1.png" alt="我的图片">
引入网上图片
[ ]
定义数组
在循环中加入 let key=idex
<h1>循环数据 显示数据索引索引h1>
<ul>
<li *ngFor="let item of piclist;let key=index ">
{{key}}---->{{item.title}}
li>
ul>
<ul>
<li *ngFor="let item of piclist;let key=index ">
<span *ngIf="key==1" class="red">{{key}}---->{{item.title}}span>
<span *ngIf="key!=1">{{key}}---->{{item.title}}span>
li>
ul>
<h1>开关*ngSwitchh1>
<div [ngSwitch]="num">
<div *ngSwitchCase="1">正确输入div>
<div *ngSwitchCase="2">重新输入div>
<div *ngSwitchDefault>错误输入div>
div>
<div [ngClass]="{'orange': flag,'blue':!flag}">
动态变化class
div>
<p [ngStyle]="{'color':'blue' }">ngStyle,固定值+单引号p>
Angular内置方法
http://bbs.itying.com/topic/5bf519657e9f5911d4f2a34
日期格式化
<h1>管道时间格式化,注意+单引号h1>
{{today | date: 'YYYY-MM-dd HH:mm:ss'}}
自定义方法
在.HTML中显示效果
<h1>事件h1>
{{num}}
<button (click)="run()">执行事件button>
<button (click)="getData()">获取数据button>
<button (click)="setData()">改变数据button>
在 .ts中写执行方法
run(){
alert("执行事件");
}
getData(){
alert(this.flag);
}
setData(){
this.num='改变后数据';
}
通过事件对象监听文本输入,得到文本响应次数,文本数据…
<button (click)="runevent($e)">监听button>
<h1>表单事件 事件对象h1>
keydown
<input type="text" (keydown)="keyDown1()">
keyup
<input type="text" (keyup)="keyUp1()">
keyDown1(){
console.log('keyDown');
}
// keyDown2(){
// if(e.keycode==1)
// {
// console.log('按下了回车')
// }
// else{
// console.log(e.keycode);
// }
// }
keyUp1(){
console.log('keyUp');
}
runevent(e)){
var dom:any=e.target;
dom.style.color="red";
}
问题
无法监听到具体内容,事件e显示未定义Model <—> View
Model改变会改变视图,反之亦然
先在 app.module.ts
中引入FormsModule
import { FormsModule } from '@angular/forms';
在ngmodules添加
同时改变
<h1>双向数据绑定---MVVM(仅针对表单)h1>
<input type="text" [(ngModel)]='keywords'> {{keywords}}
<button (click)="change()">改变keywords值button>
<div *ngIf="keywords=='1'">直接改变了,还需要监听吗div>
当前组件的样式写在当前的css文件中
全局的样式,写在根组件app.component.css
中
首先先在.ts文件定义一个对象
将预约功能中的每部分都纳入该对象中
public peopleinfo:any={
userage:'',
sex: '1',
citylist:['上海','北京','广东'],
city:'北京',
hobby:[{title:'吃饭',checked:false},{title:'睡觉',checked:true},{title:'打豆豆',checked:true}],
mark:''
}
jQuery方式
<li>姓 名: <input type="text" id="username">li>
let usernameDom:any=document.getElementById('username');
console.log(usernameDom.value)
双向数据绑定方式
<li>年 龄: <input type="text" [(ngModel)]="peopleinfo.userage">li>
可直接打印数据
双向绑定数据方式
<li>性 别:
<input type="radio" value="1" name="sex" id="sex1" [(ngModel)]="peopleinfo.sex"> <label for="sex1">男 label>
<input type="radio" value="2" name="sex" id="sex2" [(ngModel)]="peopleinfo.sex"> <label for="sex2">女 label>
双向绑定数据方式
<li>城 市:
<select name="city" id="city"
[(ngModel)]="peopleinfo.city">
<option [value]="item" *ngFor="let item of
peopleinfo.citylist">{{item}}option>select>
li>
双向绑定数据方式
<li>爱 好:
<span *ngFor="let item of peopleinfo.hobby; let
key=index;">
<input type="checkbox" [id]="'check'+key"
[(ngModel)]="item.checked"><label
[for]="'check'+key">{{item.title}}label> &nbs
p;
span>li>
双向绑定数据方式
<li>备 注:
<textarea name="mark" id="mark" cols="30" rows="10"
[(ngModel)]="peopleinfo.mark">textarea>
li>
<button (click)="doSubmit()">获取信息button>
<pre>
{{peopleinfo | json}}
pre>
命令
ng g service my-new-service
创建到指定目录下
ng g service services/storage
引入到app.module.ts
中,并配置服务
引入服务路径
import { StorageService } from './services/storage.service';
加入服务配置
providers: [StorageService], //配置项目所需要的服务
增加服务类型
当其他组件要使用服务,同样引入
更新路径
import { StorageService } from '../../services/storage.service';
实例化(初始化对象)
方法一(不推荐)
var storage=new StorageService();
console.log(storage);
方法二(推荐)
//在构造函数中初始化
constructor(public todo:StorageService)
{ }
ngOnInit(): void {
console.log('页面刷新会触发这个生命周期函数!');
var todolist=this.todo.get('todolist');
if(todolist)
{
this.todolist=todolist;
}
}
注意
:每刷新一次界面便会触发生命周期函数使用
将实例化的对象作为组件的属性进行使用,并调用方法
this.todo.set('todolist',this.todolist);
长期存储函数
set(key:any,value:any){
localStorage.setItem(key,JSON.stringify(value));
}
界面-->检查-->应用-->存储-->本地存储空间
查看
返回存取内容函数
get(key:any){
return JSON.parse(localStorage.getItem(key)||'0');
//return JSON.parse(localStorage.getItem(key)||'{}');
}
在存储空间中删除函数
remove(key:any)
{
localStorage.removeItem(key);
}
最终界面(刷新后仍保持)
生命周期函数ngOnInit
只是组件和指令初始化完成,并不是真正的dom加载 完成
ngOnInit(): void {
//组件和指令初始化完成,并不是真正的dom加载完成
let
oBox:any=document.getElementById("DOM");
console.log(oBox.innerHTML);
oBox.style.color="red";}
<div id="DOM">
这是DOM组件
</div>
当div
里 多了ngif
类操作
视图加载完后触发的方法,dom加载完毕(建议)
ngAfterViewInit():void{
let
oBox1:any=document.getElementById("DOM1");
console.log(oBox1.innerHTML);
oBox1.style.color="blue";}
<div id="DOM1" *ngIf="flag">
这是DOM组件这是
</div>
功能一: 实现DOM操作
先起名 #name
<div #dom3>
这是ViewChild方法
div>
业务逻辑中定义
@ViewChild('dom3') mybox:any;
另一个生命周期函数中使用
ngAfterViewInit():void{
//@ViewChild
console.log(this.mybox.nativeElement);
this.mybox.nativeElement.style.width='200px';
this.mybox.nativeElement.style.height='30px';
this.mybox.nativeElement.style.background='yellow';
console.log(this.mybox.nativeElement.innerHTML);
}
功能二: 父子组件中通过ViewChild调用子组件的方法
在父组件.HTML中引用子组件,并为子组件取名 # name
<app-news #child>app-news>
将子组件通过ViewChild赋给父组件的一个属性
@ViewChild('child') child:any;
通过该属性调用子组件的方法
runClick(){
this.child.runNews();
}
实现侧边栏
<aside id="aside">
这是一个侧边栏
aside>
显示侧边栏效果(使用原生JS
获取dom
)
showAside(){
//原生JS获得dom节点
let asidedom:any=document.getElementById("aside");
asidedom.style.transform="translate(0,0)";
}
设置效果
class='name' --> .name{}
id='name' --> #name{}
li --> li{}
@input
子组件可以获取父组件的数据
父组件调用子组件时传入数据
<app-child [title]="title" [msg]="msg" [run]="run" [header]="this">app-child>
子组件引入Input
模块
import { Component, OnInit ,Input} from '@angular/core';
子组件@input
接受父组件传来的数据
//input装饰器
@Input() title:any; //接收父组件传来的数据
@Input() msg:any; //接收父组件传来的数据
@Input() run:any; //接收父组件传来的数据
@Input() header:any; //接收父组件传来的数据/
子组件可以获得父组件的方法和对象
@ViewChild
主动获取子组件的数据和方法(推荐)
在父组件.HTML中引用子组件,并为子组件取名 # name
<app-news #child>app-news>
将子组件通过ViewChild赋给父组件的一个属性
@ViewChild('child') child:any;
通过该属性调用子组件的方法
runClick(){
this.child.runNews();
}
@Output
触发父组件的方法
父组件可以获取子组件的数据
子组件引入Output
和EventEmitter
(事件驱动)
import { Component, OnInit ,Input,Output,EventEmitter} from '@angular/core';
子组件中实例化EventEmitter
@Output() outer=new EventEmitter();
子组件通过EventEmitter
对象outer
实例广播数据
sendParent(){
alert('11');
this.outer.emit('我是子组件的数据');
}
父组件调用子组件时,定义接收事件,outer
就是子组件的EventEmitter
对象outer
<app-child #child (outer)="runAlart($event)"></app-child>
父组件接收到数据会调用自己的runParent()
方法,这个时候就能拿到子组件的数据
runAlart(e:any){
console.log(e);
alert('我是父组件的runAlart()方法');
}
父组件可以获取子组件的方法
localstorage
服务service
组件创建,组件更新,组件销毁时会触发的一系列方法
当Angular使用构造函数新建一个组件或指令后,就会按照以下顺序在特定时刻调用这些生命周期钩子方法
钩子方法 | 用途及时机 |
---|---|
constructor() |
构造函数中除了使用简单的值对局部变量进行初始化之外,什么都不应该做(非生命周期函数) |
ngOnChanges() |
当Angular(重新)设置数据绑定输入属性时响应,该方法接受当前和上一属性值的SimpleChanges对象,当被绑定的输入属性的值发生变化时调用,首次调用一定会发生在ngOnInit()之前 |
ngOnInit() |
在Angular第一次显示数据绑定和设置指令/组件的输入属性之后,初始化指令/组件。在第一轮ngOnChanges()完成之后调用,只调用一次。使用ngOnInit()两个原因:1.在构造函数之后马上执行复杂的初始化逻辑;2.在Angular设置完输入属性之后,对该组件进行 |
ngAfterViewInit() |
初始化完组件视图及其子视图之后调用,第一次ngAfterContentChecked()之后使用 |
ngOnDestroy() |
当Angular每次销毁指令/组件之前调用并清扫,在这里反订阅可观察对象和分离事件处理器,以防内存泄漏。在Angular销毁指令/组件之前调用。 |
RxJS是Reactive编程理念的JavaScript版本,Rx是一种针对异步数据流的编程,响应式编程,它将一切数据,包括HTTP请求,DOM事件或者其他普通数据包等包装成流的形式,然后用强大丰富的操作符对流进行处理,使能以同步编程的方式处理异步数据,并组合不同的操作符来轻松优雅的实现你所需要的功能。
Angular引入RxJS是为了让异步可控,更简单
RxJS提供很多模块,常用的是Observable,fromEvent
常见异步编程的几种方法
回调函数
服务
//回调函数 Callback()
getCallbackData(cb:any){
setTimeout(()=>{
var data=‘张三–CallBack()’;
// return data;
cb(data);
},1000)
}
- 组件
```typescript
//异步方法--回调函数
this.search.getCallbackData((b:any)=>{
console.log(b);
});
事件监听、发布订阅
Promise (es6)
服务
//Promise()
getPromiseData(){
return new Promise((resolve)=>{
setTimeout(()=>{
var data='张三--Promise()';
resolve(data);
},1000);
})
}
组件
//异步方法--Promise()
var promiseData=this.search.getPromiseData();
promiseData.then((c)=>{
console.log(c);
})
RxJS
引入Observable
import { Observable} from 'rxjs';
服务
//RxJS获取异步方法里的数据
getRxjsData(){
return new Observable((observer)=>{
//定时器
setTimeout(() => {
var data='张三--RxJS()';
observer.next(data);
// observer.error('数据');
}, 2000);
})
}
组件
//异步方法--RxJS()
var rxjsData=this.search.getRxjsData();
rxjsData.subscribe((d)=>{
console.log(d);
})
Promise创建后,动作无法撤回,Observable的动作可以通过unsubscribe
方法中途撤回,且在内部做了智能的处理。
//异步方法--RxJS(),动作撤回,组件
var stream=this.search.getRxjsData();
var data=stream.subscribe((d)=>{
console.log(d);
})
setTimeout(() => {
data.unsubscribe(); //取消订阅
}, 1000);
Promise最终结果要么reclose(兑现),要么reject(拒绝),且只能触发一次,若在同一个Promise对象上多次调用resolve方法,就会抛出异常。
observable可以不断触发下一个值,next();(爬虫)
服务
//Rxjs 多次执行
getRxjsIntervalData(){
let count =0;
return new Observable<any>((observer)=>{
setInterval(()=>{
count++;
var username='张三--Rxjs--Interval'+count;
observer.next(username);
},1000)
})
}
组件
//7. rxjs执行多次
var streamInterval=this.search.getRxjsIntervalData();
streamInterval.subscribe((f)=>{
console.log(f);
})
filter+pipe
//8.pipe,filter
var streamInterval1=this.search.getRxjsIntervalData();
streamInterval1.pipe(
filter((value:any):any=>{
if(value%2==0)
return true;
})
).subscribe((f)=>{
console.log(f);
})
map+pipe
//9.map()
var streamInterval2=this.search.getRxjsIntervalData();
streamInterval2.pipe(
map((value:any):any=>{
if(value%2==0)
return value*value;
})
).subscribe((f)=>{
console.log(f);
})
pipe-filter-map
//10. pipe,filter,map,连续先过滤再处理数据
var streamInterval1=this.search.getRxjsIntervalData();
streamInterval1.pipe(
filter((value:any):any=>{
if(value%2==0)
return true;
}),
map((value:any):any=>{
if(value%10==0)
return value*value;
})
).subscribe((f)=>{
console.log(f);
})
RSJS6改变了包的结构,主要变化在import方式和operator上面以及使用pipe()
import { filter, map } from 'rxjs';
HttpClientModule
模块。在app.modiles.ts
中引入HttpClientModule
并注入
import { HttpClientModule } from '@angular/common/http';
imports: [ //配置当前模块运行依赖的其他模块
BrowserModule,FormsModule,HttpClientModule
],
在用到的地方引入HttpClient
并在构造函数中声明
constructor(public http:HttpClient) { }
get
请求数据
getData(){
// alert('get请求数据');
//服务器必须跨域
let api="http://a.itying.com/api/productlist";
this.http.get(api).subscribe((response:any)=>{
console.log(response);
this.list=response.result;
})
}
在app.modiles.ts
中引入HttpClientModule
并注入
import { HttpClientModule } from '@angular/common/http';
imports: [ //配置当前模块运行依赖的其他模块
BrowserModule,FormsModule,HttpClientModule
],
在用到的地方引入HttpClient
,HttpHeaders
并在构造函数中声明HttpClient
,需设置请求头
//当作一个服务
import { HttpClient,HttpHeaders } from '@angular/common/http';
constructor(public http:HttpClient) { }
post
请求数据
dologin(){
// alert('sub');
//手动设置请求的类型
const httpOption={headers:new HttpHeaders({'Content-Type':'application/json'})}
//存在跨域
let api='http://127.0.0.1:3000/dologin';
this.http.post(api,{"username":"张三","age":"20"},httpOption).subscribe((reply)=>{
console.log(reply);
});
}
在app.modiles.ts
中引入HttpClientModule,HttpClientJsonpModule
并注入
//引入数据交互模块
import { HttpClientModule,HttpClientJsonpModule } from '@angular/common/http';
imports: [ //配置当前模块运行依赖的其他模块
BrowserModule,FormsModule,HttpClientModule,
HttpClientJsonpModule
],
在用到的地方引入HttpClient
,并在构造函数中声明HttpClient
constructor(public http:HttpClient) { }
Jsonp
请求数据
getJsonpData(){
// alert('Jsonp');
//网络-右键-在新的标签页打开
let api="http://a.itying.com/api/productlist";
this.http.jsonp(api,'callback').subscribe((response)=>{
console.log(response);
})
}
安装axios
cnpm installl axios --save
ng serve --open
在用到的地方引入axios
创建服务和方法
ng g service services/httpservice
//用promise封装异步,也可用rxjs
axiosGet(api:any){
//用promise封装异步,也可用rxjs
return new Promise((resolve:any,reject:any)=>{
axios.get(api)
.then(function(response:any){
//handle success
// console.log(response);
resolve(response);
})
.catch(function (error:any){
//handle error
console.log(error);
})
})}
引入服务,并配置app.module.ts
import { HttpserviceService } from './services/httpservice.service';
providers: [StorageService,HttpserviceService], //配置项目所需要的服务
在使用服务的.ts文件中引入服务
//使用服务里的axios获取数据
import { HttpserviceService } from '../../services/httpservice.service';
在构造函数中定义对象并初始化
constructor(public http:HttpClient,public httpservice:HttpserviceService ) { }
使用方法
getAxiosData(){
let api="http://a.itying.com/api/productlist";
this.httpservice.axiosGet(api).then((data)=>{
console.log(data);
})
}
看文档使用
url地址
,动态
地让根组件挂在其他组件来实现按一个单页面应用命令创建项目
ng new Route --skip-install
-y
-scss
//转到项目里
cd Route
//建立依赖
cnpm install
app
多了个配置路由的app-routing-modules.ts
文件,app.module.ts
也多了引入模块创建需要的组件
ng g component components/product
ng g component components/news
ng g component components/home
app-routing-modules.ts
引入组件,并配置路由
//引入挂载模块
import { NewsComponent } from './components/news/news.component';
import { HomeComponent } from './components/home/home.component';
import { ProductComponent } from './components/product/product.component';
//配置路由
const routes: Routes = [
{ path:'home',component:HomeComponent},
{ path:'news',component:NewsComponent},
{ path:'product',component:ProductComponent}
];
更改url,访问挂载的不同组件,其放在(手动更改配置)
//可决定位置
<router-outlet></router-outlet>
//根组件网址
http://localhost:4200/
//挂载的网址url
http://localhost:4200/home
http://localhost:4200/news
http://localhost:4200/product
改为通过点击实现跳转界面
找到app.component.html
根组件模块,配置router-outlet
显示动态加载的路由 (.html)
<a [routerLink]="['/home']">首页</a>
<a routerLink='/news'>新闻</a>
<a routerLink='/product'>商品</a>
比传统方式响应快些
在路由文件中增加匹配不到路由时,默认跳转到的界面
//配置路由
const routes: Routes = [
{ path:'home',component:HomeComponent},
{ path:'news',component:NewsComponent},
{ path:'product',component:ProductComponent},
//匹配不到路由时,默认挂载的组件
{path:'**',redirectTo:'news'}
];
可设置选中后的样式
<a [routerLink]="['/home']" routerLinkActive="router-link-active">首页</a>
<a routerLink='/news' routerLinkActive="router-link-active">新闻</a>
<a routerLink='/product' routerLinkActive="router-link-active">商品</a>
跳转
<ul>
<li *ngFor="let item of list;let key=index">
<a [routerLink]="['/news-content']" [queryParams]="{aid:key}">
{{key}}---{{item}}
</a>
</li>
</ul>
接收
import { ActivatedRoute } from '@angular/router';
constructor(public route:ActivatedRoute) { }
ngOnInit(): void {
console.log(this.route);
this.route.queryParams.subscribe((data)=>{
console.log(data);
})
}
配置动态路由
//配置路由
const routes: Routes = [
{ path:'home',component:HomeComponent},
{ path:'news',component:NewsComponent},
{ path:'product',component:ProductComponent},
{ path:'newscontent/:aid',component:NewscontentComponent},
//匹配不到路由时,默认挂载的组件
{path:'**',redirectTo:'home'}
];
跳转
<h2>动态路由h2>
<ul>
<li *ngFor="let item of list;let key=index">
<a [routerLink]="['/newscontent/',key]">
{{key}}--{{item}}
a>
li>
ul>
接收
//动态路由获取url的传值
this.route.params.subscribe((data)=>{
console.log(data);
})
引入
import { Router } from '@angular/router';
初始化,声明
constructor(public router:Router) { }
跳转
getProductContent(){
// alert('js');
//路由跳转, 动态路由
this.router.navigate(['/productcontent/','134']);
}
//路由跳转, 普通路由
ToHome(){
this.router.navigate(['/home/']);
}
引入NavigationExtras
import { Router ,NavigationExtras } from ‘@angular/router’;
定义一个goNews
方法执行跳转,用NavigationExtras
配置传参并跳转
//get传值
goNews(){
//跳转并进行get传值
//传参
let queryParams:NavigationExtras={
queryParams:{'aid':123}
}
this.router.navigate(['/news'],queryParams);
}
应用场景
创建组件引入组件
直接在父组件目录下创建,更加直白
ng g component components/home/welcome
引入,app.module.ts
自动引入,在app-routing.module.ts
//子组件
import { WelcomeComponent } from './components/home/welcome/welcome.component';
import { SettingComponent } from './components/home/setting/setting.component';
import { PcateComponent } from './components/child/pcate/pcate.component';
import { PlistComponent } from './components/child/plist/plist.component';
配置路由
直接在父路由配置下嵌套配置,可设置默认
//配置路由
const routes: Routes = [
{
path:'home',component:HomeComponent,
children:[
{ path:'welcome',component:WelcomeComponent},
{ path:'setting',component:SettingComponent},
//可以再叠加使用默认
{ path:'**',redirectTo:'welcome'}
]
}]
注意:还需要在父组件.html文件下添加,使得匹配到的子路由组件能够挂载在父路由上
<router-outlet>
router-outlet>
管理员身份打开命令提示符
D:
cd angular #切换到存入目录
ng new case --skip-install #创建项目
route --y #选择路由
css/scss... #任选
cd case #切换到项目里
cnpm install #安装依赖
将项目拖拽到VS code中,在VS code终端操作
ng serve --open #试运行
创建组件(数量按需要定)
ng g component components/home #组件
ng g component components/conduct #组件
将组件引入路由,并配置
//引入
import { HomeComponent } from './components/home/home.component';
import { ProductComponent } from './components/product/product.component';
//配置路由
const routes: Routes = [
{ path:'home',component:HomeComponent},
{ path:'product',component:ProductComponent},
//默认路由
{ path:'**',redirectTo:'home'}
];
在创建项目时,选择路由即体现在app.component.html
中会出现
<router-outlet>router-outlet>
ting.component’;
import { PcateComponent } from ‘./components/child/pcate/pcate.component’;
import { PlistComponent } from ‘./components/child/plist/plist.component’;
```
配置路由
直接在父路由配置下嵌套配置,可设置默认
//配置路由
const routes: Routes = [
{
path:'home',component:HomeComponent,
children:[
{ path:'welcome',component:WelcomeComponent},
{ path:'setting',component:SettingComponent},
//可以再叠加使用默认
{ path:'**',redirectTo:'welcome'}
]
}]
注意:还需要在父组件.html文件下添加,使得匹配到的子路由组件能够挂载在父路由上
<router-outlet>
router-outlet>
管理员身份打开命令提示符
D:
cd angular #切换到存入目录
ng new case --skip-install #创建项目
route --y #选择路由
css/scss... #任选
cd case #切换到项目里
cnpm install #安装依赖
将项目拖拽到VS code中,在VS code终端操作
ng serve --open #试运行
创建组件(数量按需要定)
ng g component components/home #组件
ng g component components/conduct #组件
将组件引入路由,并配置
//引入
import { HomeComponent } from './components/home/home.component';
import { ProductComponent } from './components/product/product.component';
//配置路由
const routes: Routes = [
{ path:'home',component:HomeComponent},
{ path:'product',component:ProductComponent},
//默认路由
{ path:'**',redirectTo:'home'}
];
在创建项目时,选择路由即体现在app.component.html
中会出现
<router-outlet>router-outlet>
没数据,暂时不继续!