寫在前面
本文的所有內(nèi)容,可以在我的博客上看到,下面是地址。建議去博客看,因?yàn)閏sdn的這篇圖片我沒上傳。
可以轉(zhuǎn)載,但請(qǐng)注明出處
我的博客—點(diǎn)擊跳轉(zhuǎn)
https://numb.run
angular
Angular介紹
Angular是谷歌開發(fā)的一款開源的web前端框架,誕生于2009年,由Misko Hevery 等人創(chuàng)建,后為Google所收購。是一款優(yōu)秀的前端JS框架,已經(jīng)被用于Google的多款產(chǎn)品當(dāng)中。
根據(jù)項(xiàng)目數(shù)統(tǒng)計(jì)angular(1.x 、2.x 、4.x、5.x、6.x、7.x 、8.x、9.x)是現(xiàn)在網(wǎng)上使用量最大的框架。
Angular基于TypeScript和react、vue相比 Angular更適合中大型企業(yè)級(jí)項(xiàng)目。
Angular環(huán)境搭建
1、安裝前準(zhǔn)備工作:
1.1、安裝nodejs
安裝angular的計(jì)算機(jī)上面必須安裝最新的nodejs–注意安裝nodejs穩(wěn)定版本
1.2、選擇一個(gè) 命令工具, npm, cnpm, yarn ,任選其一
設(shè)置淘寶源鏡像 ,如果你用npm
npm config set registry https://registry.npm.taobao.org
如果你用cnpm , 安裝cnpm
npm可能安裝失敗建議先用npm安裝一下cnpm用淘寶鏡像安裝
https://npm.taobao.org/
npm install -g cnpm --registry=https://registry.npm.taobao.org
或者 安裝yarn ,注意,只要選 一個(gè)命令工具就行
yarn
npm install yarn -g
然后切換為淘寶源你才能感受到速度:
yarn config set registry https://registry.npm.taobao.org --global
yarn config set disturl https://npm.taobao.org/dist --global
好了,真的很簡(jiǎn)單,它的命令與npm幾乎一樣:
- 初始化:yarn init
- 安裝一個(gè)包:yarn add 包名
- 更新一個(gè)包:yarn upgrade 包名
- 刪除一個(gè)包:yarn remove 包名
- 安裝所有包:yarn或者yarn install
安裝Angular CLI
- 全局安裝typescript(可選)
$ npm install -g typescript
// 新建項(xiàng)目的時(shí)候會(huì)自動(dòng)安裝typescript(非全局)所以這里也可以不用安裝。 - 全局安裝Angular CLI
yarn global add @angular/cli 或者 npm install @angular/cli -g
- 如果要卸載,執(zhí)行下面命令:
yarn global remove @angular/cli
經(jīng)過不算漫長的等待,你的Angular CLI就裝好了。確認(rèn)一下:
- 檢驗(yàn)安裝是否成功
ng version 或者 ng v
新建Angular項(xiàng)目
新建Angular項(xiàng)目
ng new my-app
如果要跳過npm i安裝
ng new my-app --skip-install
趁著它在下載,來看一下運(yùn)行ng new之后Angular cli已經(jīng)幫我們干了什么:
那么,這時(shí)候Angular cli幫你干了以下這么多事情:
- 創(chuàng)建 my-app 目錄
- 應(yīng)用程序相關(guān)的源文件和目錄將會(huì)被創(chuàng)建
- 應(yīng)用程序的所有依賴 (package.json中配置的依賴項(xiàng)) 將會(huì)被自動(dòng)安裝
- 自動(dòng)配置項(xiàng)目中的 TypeScript 開發(fā)環(huán)境
- 自動(dòng)配置 Karma 單元測(cè)試環(huán)境
- 自動(dòng)配置 Protractor (end-to-end) 測(cè)試環(huán)境
- 創(chuàng)建 environment 相關(guān)的文件并初始化為默認(rèn)的設(shè)置
啟動(dòng)項(xiàng)目
安裝完成之后就可以啟動(dòng)項(xiàng)目了:
cd my-app //進(jìn)入my-app
npm start 或者 ng serve //啟服務(wù)
ng serve命令會(huì)啟動(dòng)開發(fā)服務(wù)器,監(jiān)聽文件變化,并在修改這些文件時(shí)重新構(gòu)建此應(yīng)用。
使用–open(或-o)參數(shù)可以自動(dòng)打開瀏覽器并訪問http://localhost:4200/。
ng serve命令提供了很多參數(shù),可以適當(dāng)參考。
以下參數(shù)僅供參考:
--dry-run: boolean, 默認(rèn)為 false, 若設(shè)置 dry-run 則不會(huì)創(chuàng)建任何文件
--verbose: boolean, 默認(rèn)為 false
--link-cli: boolean, 默認(rèn)為 false, 自動(dòng)鏈接到 @angular/cli 包
--skip-install: boolean, 默認(rèn)為 false, 表示跳過 npm install
--skip-git: boolean, 默認(rèn)為 false, 表示該目錄不初始化為 git 倉庫
--skip-tests: boolean, 默認(rèn)為 false, 表示不創(chuàng)建 tests 相關(guān)文件
--skip-commit: boolean, 默認(rèn)為 false, 表示不進(jìn)行初始提交
--directory: string, 用于設(shè)置創(chuàng)建的目錄名,默認(rèn)與應(yīng)用程序的同名
--source-dir: string, 默認(rèn)為 'src', 用于設(shè)置源文件目錄的名稱
--stylring, 默認(rèn)為 'css', 用于設(shè)置選用的樣式語法 ('css', 'less' or 'scss')
--prefix: string, 默認(rèn)為 'app', 用于設(shè)置創(chuàng)建新組件時(shí),組件選擇器使用的前綴
--mobile: boolean, 默認(rèn)為 false,表示是否生成 Progressive Web App 應(yīng)用程序
--routing: boolean, 默認(rèn)為 false, 表示新增帶有路由信息的模塊,并添加到根模塊中
--inline-style: boolean, 默認(rèn)為 false, 表示當(dāng)創(chuàng)建新的應(yīng)用程序時(shí),使用內(nèi)聯(lián)樣式
--inline-template: boolean, 默認(rèn)為 false, 表示當(dāng)創(chuàng)建新的應(yīng)用程序時(shí),使用內(nèi)聯(lián)模板
其他文件:
.editorconfig: 給你的編輯器看的一個(gè)簡(jiǎn)單配置文件
.gitignore: git 排除文件
angular.json: angular cli 的配置文件
package.json:npm 配置文件,項(xiàng)目使用到的第三方依賴包
protractor.conf.js- :運(yùn)行 ng e2e 的時(shí)候會(huì)用到
README.md:項(xiàng)目的基礎(chǔ)文檔
tsconfig.json:TypeScript 編譯器的配置
tslint.json:運(yùn)行 ng lint 時(shí)會(huì)用到
Angular CLI簡(jiǎn)單使用
新建組件
ng generate component news
-
installing component
- create src/app/great-angular/news.component.css
- create src/app/great-angular/news.component.html
- create src/app/great-angular/news.component.spec.ts
- create src/app/great-angular/news.component.ts
- update src/app/app.module.ts
如你所見,Angular cli幫我們干了如下事情:
-
src/app/news 目錄被創(chuàng)建
-
news目錄下會(huì)生成以下四個(gè)文件:
-
CSS 樣式文件,用于設(shè)置組件的樣式
-
HTML 模板文件,用于設(shè)置組件的模板
-
TypeScript 文件,里面包含一個(gè) 組件類和組件的元信息
-
Spec 文件,包含組件相關(guān)的測(cè)試用例
-
news 組件會(huì)被自動(dòng)地添加到 app.module.ts @NgModule 裝飾器的 declarations 屬性中。
其他命令
Angualr CLI提供了許多常用命令供我們選擇:
- ng generate class my-new-class // 新建類, 新建一個(gè)名為my-new-class的類 (class)
- ng generate component my-new-component // 新建組件
- ng generate directive my-new-directive // 新建指令
- ng generate enum my-new-enum // 新建枚舉
- ng generate module my-new-module // 新建模塊
- ng generate pipe my-new-pipe // 新建管道
- ng generate service my-new-service // 新建服務(wù)
當(dāng)然選擇。。簡(jiǎn)寫:
- ng g cl my-new-class // 新建 class
- ng g c my-new-component // 新建組件
- ng g d my-new-directive // 新建指令
- ng g e my-new-enum // 新建枚舉
- ng g m my-new-module // 新建模塊
- ng g p my-new-pipe // 新建管道
- ng g s my-new-service // 新建服務(wù)
單元測(cè)試
Angular默認(rèn)幫我們集成了``karma`測(cè)試框架,我們只需要:
ng test
端到端測(cè)試
ng e2e
構(gòu)建應(yīng)用程序
ng build
其中過程應(yīng)該是這樣的:
Angular CLI 從 .angular-cli.json 文件中加載配置信息
Angular CLI 運(yùn)行 Webpack 打包項(xiàng)目相關(guān)的 html、 CSS 等文件
打包后的資源,將被輸出到配置文件中 outDir 所指定的目錄,默認(rèn)是輸出到 dist 目錄。
Angular開發(fā)工具介紹
Visual Studio Code
[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來直接上傳(img-ORjkQo3I-1651495956860)(/pic/plugin.png)]
Angular目錄結(jié)構(gòu)分析
app.module.ts詳解、以及Angular中創(chuàng)建組件、組件詳解、 綁定數(shù)據(jù)
目錄結(jié)構(gòu)分析
文件 說明
|--E2e 應(yīng)用的端對(duì)端(e2e)測(cè)試,用 Jasmine 寫成并用 protractor 端對(duì)端測(cè)試運(yùn)行器測(cè)試。
|--Node_modules 依賴包
|--Src
|--App Angular應(yīng)用文件
|--App.module.ts
|---App.component.ts
|--assets 資源文件
|--environments 環(huán)境配置:開發(fā)、部署
|--index.html 應(yīng)用的宿主頁面。 它以特定的順序加載一些基本腳本。 然后它啟動(dòng)應(yīng)用,將根AppComponent放置到自定義<my-app>標(biāo)簽里。
|--main.ts 項(xiàng)目的入口文件
|--polyfills.ts 處理瀏覽器兼容問題
|--angular.json Cli配置文件
|--.editorconfig 統(tǒng)一代碼風(fēng)格工具配置,不支持的需要安裝插件
|--.gitignore Git配置文件
|--karma.conf.js 在測(cè)試指南中提到的 karma 測(cè)試運(yùn)行器的配置。
|--package.json 項(xiàng)目指定npm依賴包
|--tsconfig.app.json Typescript編譯配置
|--tsconfig.spec.json Typescript測(cè)試編譯配置
|--tsconfig.json Typescript編譯配置
|--tslint.json Typescript語法檢查器
詳情參考:https://www.angular.cn/guide/file-structure
app.module.ts、組件分析
app.module.ts
定義 AppModule,這個(gè)根模塊會(huì)告訴 Angular 如何組裝該應(yīng)用。 目前,它只聲明了 AppComponent。 稍后它還會(huì)聲明更多組件。
[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來直接上傳(img-pGZAwauA-1651495956863)(/pic/app-module.png)]
自定義組件
https://cli.angular.io/
創(chuàng)建組件:
ng g component components/header
組件內(nèi)容詳解:
[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來直接上傳(img-OGKhQOFr-1651495956870)(/pic/module-de.png)]
app.component.ts組件分析
Angular應(yīng)用中,模板指的的是@Component裝飾器的template或templateUrl指向的HTML頁面
例如:
import { Component } from '@angular/core';
interface Course {
id:number,
description:string
}
@Component({
selector: 'app-root',
// templateUrl: './app.component.html',
template:`
<div class="course">
<span class="description">{{courseObj.description}}</span>
</div>
`,
styleUrls: ['./app.component.css']
})
export class AppComponent{
title = 'ng-module-routes';
id:number = 1;
description:string = 'sss';
public courseObj: Course = {
id: 1,
description: "Angular For Beginners"
};
}
很明顯Angular不是簡(jiǎn)單地用一個(gè)字符串來處理模板。 那么這是如何工作的?
Angular不會(huì)生成HTML字符串,它直接生成DOM數(shù)據(jù)結(jié)構(gòu)
實(shí)際上,Angular把組件類中的數(shù)據(jù)模型應(yīng)用于一個(gè)函數(shù)(DOM component renderer)。 該函數(shù)的輸出是對(duì)應(yīng)于此HTML模板的DOM數(shù)據(jù)結(jié)構(gòu)。
一旦數(shù)據(jù)狀態(tài)發(fā)生改變,Angular數(shù)據(jù)檢測(cè)器檢測(cè)到,將重新調(diào)用
該DOM component renderer。
mvvm
Mvvm定義MVVM是Model-View-ViewModel的簡(jiǎn)寫。即模型-視圖-視圖模型。
- 【模型】指的是后端傳遞的數(shù)據(jù)。
- 【視圖】指的是所看到的頁面。
- 【視圖模型】mvvm模式的核心,它是連接view和model的橋梁。
它有兩個(gè)方向:
- 一是將【模型】轉(zhuǎn)化成【視圖】,即將后端傳遞的數(shù)據(jù)轉(zhuǎn)化成所看到的頁面。實(shí)現(xiàn)的方式是:數(shù)據(jù)綁定。
- 二是將【視圖】轉(zhuǎn)化成【模型】,即將所看到的頁面轉(zhuǎn)化成后端的數(shù)據(jù)。
實(shí)現(xiàn)的方式是:DOM 事件監(jiān)聽。這兩個(gè)方向都實(shí)現(xiàn)的,我們稱之為數(shù)據(jù)的雙向綁定。
總結(jié)
在MVVM的框架下視圖和模型是不能直接通信的。它們通過ViewModel來通信,ViewModel通常要實(shí)現(xiàn)一個(gè)observer觀察者,當(dāng)數(shù)據(jù)發(fā)生變化,ViewModel能夠監(jiān)聽到數(shù)據(jù)的這種變化,然后通知到對(duì)應(yīng)的視圖做自動(dòng)更新,而當(dāng)用戶操作視圖,ViewModel也能監(jiān)聽到視圖的變化,然后通知數(shù)據(jù)做改動(dòng),這實(shí)際上就實(shí)現(xiàn)了數(shù)據(jù)的雙向綁定。
并且MVVM中的View 和 ViewModel可以互相通信。MVVM流程圖如下:
[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來直接上傳(img-pqm1GH7N-1651495956873)(/pic/img-mv.png)]
angular 組件 以及組件里面的模板
Angular 綁定數(shù)據(jù)
數(shù)據(jù)文本綁定
Angular 中使用{{}}綁定業(yè)務(wù)邏輯里面定義的數(shù)據(jù)
{{}}
<div class="title"> {{title}}</div>
{{userinfo.username}} {{message}} {{student}}
angualr模板里面綁定屬性
<div [title]="student">
張三
</div>
angualr模板里面綁定Html
<span [innerHTML]='content' class="red"></span>
angualr模板里面允許做簡(jiǎn)單的運(yùn)算
1+2={{1+2}}
數(shù)據(jù)循環(huán) *ngFor
*ngFor 普通循環(huán)
<ul>
<li *ngFor="let item of list">{{item}}</li>
</ul>
循環(huán)的時(shí)候設(shè)置 key
<ul>
<li *ngFor="let item of list;let key=index;">
{{key}}---{{item.title}}
</li>
</ul>
條件判斷語句 *ngIf
<div *ngIf="flag">
<img src="assets/images/02.png" />
</div>
<div *ngIf="!flag">
<img src="assets/images/01.png" />
</div>
<ul>
<li *ngFor="let item of list;let key=index;">
<span *ngIf="key==1" class="red">{{key}}---{{item.title}}</span>
<span *ngIf="key!=1">{{key}}---{{item.title}}</span>
</li>
</ul>
條件判斷語句 *ngSwitch
<span [ngSwitch]="orderStatus">
<p *ngSwitchCase="1">
表示已經(jīng)支付
</p>
<p *ngSwitchCase="2">
支付并且確認(rèn)訂單
</p>
<p *ngSwitchCase="3">
表示已經(jīng)發(fā)貨
</p>
<p *ngSwitchCase="4">
表示已經(jīng)收貨
</p>
<p *ngSwitchDefault>
無效訂單
</p>
</span>
屬性[ngClass]
<div class="red">
ngClass演示 (盡量不要用dom來改變class)
</div>
<div [ngClass]="{'blue':true,'red':false}">
ngClass演示
</div>
<div [ngClass]="{'orange':flag,'red':!flag}">
ngClass演示
</div>
<strong>循環(huán)數(shù)組,讓數(shù)組的第一個(gè)元素的樣式為red ,第二個(gè)為orange,第三個(gè)為blue</strong>
<ul>
<li *ngFor="let item of list;let key=index;" [ngClass]="{'red':key==0,'orange':key==1,'blue':key==2}">
{{key}}---{{item.title}}
</li>
</ul>
屬性[ngStyle]
<p style="color:red">我是一個(gè)p標(biāo)簽</p>
<p [ngStyle]="{'color':'blue'}">我是一個(gè)p標(biāo)簽</p>
<p [ngStyle]="{'color': attr}">我是一個(gè)p標(biāo)簽 </p>
管道
類似于vue2的filtter
{{today | date:'yyyy-MM-dd HH:mm ss'}}
執(zhí)行事件(click)
home.component.html
<strong>{{title}}</strong>
<button (click)="run()">執(zhí)行事件</button>
<button (click)="setData()">執(zhí)行方法改變屬性里面的數(shù)據(jù)</button>
<button (click)="runEvent($event)">執(zhí)行方法獲取事件對(duì)象</button>
home.component.ts
run(){
console.log('這是一個(gè)自定義方法')
console.log(this.title);
}
setData(){
this.title='我是一個(gè)改變后的title';
}
// $event
runEvent(event){
//ionic必須這樣寫
let dom:any=event.target;
dom.style.color="red";
}
表單事件 事件對(duì)象
home.component.ts
keyDown
<input type="text" (keydown)="keyDown($event)" />
<br>
keyUp:
<input type="text" (keyup)="keyUp($event)" />
home.component.ts
keyDown(e){
if(e.keyCode==13){
console.log('按了一下回車')
}else{
//e.target 獲取dom對(duì)象
console.log(e.target.value);
}
}
keyUp(e){
if(e.keyCode==13){
console.log(e.target.value);
console.log('按了一下回車');
}
}
雙向數(shù)據(jù)綁定–MVVM 只是針對(duì)表單
<input [(ngModel)]="inputValue">
- 在app.module.ts導(dǎo)入FormsModule
- 并在imports導(dǎo)入
import { FormsModule } from '@angular/forms';
....
imports: [ /*配置當(dāng)前模塊運(yùn)行依賴的其他模塊*/
FormsModule
],
使用:
<input type="text" [(ngModel)]='keywords' />
{{keywords}}
<button (click)="changeKeywords()">改變keywords的值</button>
Angular 配置文件常見配置注解
angular.json, 這個(gè)文件是整個(gè)項(xiàng)目的概要,包含了 不同的環(huán)境,測(cè)試、代理、第三方資源 和 眾多內(nèi)置工具。
angular.json
{
"$schema": "./node_modules/@angular/cli/lib/config/schema.json", //angular-cli.json規(guī)則文件
"version": 1, // 指明了Angular 工作空間 概要的版本。
"newProjectRoot": "projects",//定義了由CLI創(chuàng)建的新的內(nèi)部應(yīng)用和庫放置的位置。默認(rèn)值為`projects`
"projects": { //包含了工作空間中所有項(xiàng)目的配置信息。
"angularTest": { //項(xiàng)目配置詳情(項(xiàng)目名稱)
"root": "", //指定了項(xiàng)目文件的根文件夾,可能為空,但是它指定了一個(gè)特定的文件夾。
"sourceRoot": "src",//指定了項(xiàng)目源文件位置
"projectType": "application",//表明了 項(xiàng)目的狀態(tài) 是 `appliaction`還是`library`。
"prefix": "app",//當(dāng)CLI創(chuàng)建 `component`或者`directive`時(shí),使用該屬性來區(qū)別他們。組件selector默認(rèn)前綴
"schematics": {},
"architect": {//自定義自動(dòng)化命令
"build": { //build模塊配置
"builder": "@angular-devkit/build-angular:browser",//build執(zhí)行的自動(dòng)化程序
"options": {
"outputPath": "dist/angularTest",//編譯后的輸出目錄,默認(rèn)為dist
"index": "src/index.html", //指定首頁文件,默認(rèn)值為"index.html"
"main": "src/main.ts", //指定應(yīng)用的入門文件
"polyfills": "src/polyfills.ts",// 指定polyfill文件
"tsConfig": "src/tsconfig.app.json",//指定tsconfig文件
"assets": [ //記錄資源文件夾,構(gòu)建時(shí)復(fù)制到`outDir`指定的目錄
"src/favicon.ico",//網(wǎng)站ico圖標(biāo)
"src/assets"
],
"styles": [//引入全局樣式,構(gòu)建時(shí)會(huì)打包進(jìn)來,常用于第三方庫引用樣式
"src/styles.css"
],
"scripts": [ ]// 引入全局腳本,構(gòu)建時(shí)會(huì)打包進(jìn)來,常用語第三方庫引入的腳本
},
"configurations": {//代表這個(gè)命令的多種調(diào)用模式
"production": {//打包命令-–prod()的配置
"fileReplacements": [
{
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.prod.ts"
}
],
"optimization": true,
"outputHashing": "all",
"sourceMap": false,
"extractCss": true,
"namedChunks": false,
"aot": true,
"extractLicenses": true,
"vendorChunk": false,
"buildOptimizer": true
}
}
},
"serve": {//serve模塊配置
"builder": "@angular-devkit/build-angular:dev-server",//serve執(zhí)行的自動(dòng)化程序
"options": {
"browserTarget": "angularTest:build"
},
"configurations": {
"production": {
"browserTarget": "angularTest:build:production"
}
}
},
"extract-i18n": {
"builder": "@angular-devkit/build-angular:extract-i18n",
"options": {
"browserTarget": "angularTest:build"
}
},
"test": {
"builder": "@angular-devkit/build-angular:karma",
"options": {
"main": "src/test.ts",
"polyfills": "src/polyfills.ts",
"tsConfig": "src/tsconfig.spec.json",
"karmaConfig": "src/karma.conf.js",
"styles": [
"src/styles.css"
],
"scripts": [],
"assets": [
"src/favicon.ico",
"src/assets"
]
}
},
"lint": {
"builder": "@angular-devkit/build-angular:tslint",
"options": {
"tsConfig": [
"src/tsconfig.app.json",
"src/tsconfig.spec.json"
],
"exclude": [
"**/node_modules/**"
]
}
}
}
},
"angularTest-e2e": { //項(xiàng)目測(cè)試詳細(xì)配置
"root": "e2e/",
"projectType": "application",
"architect": {
"e2e": {
"builder": "@angular-devkit/build-angular:protractor",
"options": {
"protractorConfig": "e2e/protractor.conf.js",
"devServerTarget": "angularTest:serve"
},
"configurations": {
"production": {
"devServerTarget": "angularTest:serve:production"
}
}
},
"lint": {
"builder": "@angular-devkit/build-angular:tslint",
"options": {
"tsConfig": "e2e/tsconfig.e2e.json",
"exclude": [
"**/node_modules/**"
]
}
}
}
}
},
"defaultProject": "angularTest"//當(dāng)使用CLI命令時(shí),`defaultProject`代表顯示的名字。
}
組件通信
父?jìng)髯?@input
- 給子組件標(biāo)簽自定義一個(gè)屬性
[model]="toolbarPanel"
<nx-zlw-toolbar-panel #toolbarInstance [model]="toolbarPanel"></nx-zlw-toolbar-panel>
- 子組件引入 Input 模塊
import { Input } from '@angular/core';
//在class里面接收
@Input('model')
model: NxToolbarPanel;
//子組件中 @Input 接收父組件傳過來的數(shù)據(jù)
export class HeaderComponent implements OnInit {
@Input() title:string
constructor() { }
ngOnInit() {}
}
- 子組件執(zhí)行父組件的方法
也可以通過傳值,然后直接this.調(diào)用即可
子傳父-@ViewChild
通過 @ViewChild
- 父組件 引入
import { ViewChild } from '@angular/core';
- 在子組件上
<nx-zlw-form-list #formListInstance
加一個(gè)#號(hào);通過# - 在父組件class內(nèi)部,利用屬性裝飾器ViewChild,和剛才的子組件關(guān)聯(lián)起來
@ViewChild('formListInstance', { static: false })
formListInstance: any;
// 然后就可以通過this.formListInstance獲取這個(gè)子組件了.
-@Output
子組件通過-@Output觸發(fā)父組件的方法
演示例子:
父組件:news
子組件:footer
-
子組件引入 Output 和 EventEmitter
import { Component, OnInit ,Input,Output,EventEmitter} from ‘@angular/core’; -
子組件中實(shí)例化 EventEmitter
@Output()
private outer=new EventEmitter<string>();
/*用 EventEmitter 和 output 裝飾器配合使用 <string>指定類型變量*/
- 子組件通過 EventEmitter 對(duì)象 outer 實(shí)例廣播數(shù)據(jù)
sendParent(){
this.outer.emit('msg from child')
}
[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來直接上傳(img-5nJHXyJ4-1651495956875)(/pic/子組件觸發(fā)父組件的方法01.png)]
- 父組件調(diào)用子組件的時(shí)候,定義接收事件,outer 就是子組件的 EventEmitter 對(duì)象 outer
<!-- data就是 子組件給父組件的數(shù)據(jù) outer是定義的事件名稱-->
<app-footer (outer)="getFooterRun(data)"></app-footer>
[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來直接上傳(img-2qpXTRh0-1651495956877)(/pic/子組件觸發(fā)父組件的方法02.png)]
- 父組件接收到數(shù)據(jù)會(huì)調(diào)用自己的 getFooterRun 方法,這個(gè)時(shí)候就能拿到子組件的數(shù)
//接收子組件傳遞過來的數(shù)據(jù)
getFooterRun(data){
console.log(data);
}
非父子組件通訊
- 公共的服務(wù)
- Localstorage(推薦)
- Cookie
總結(jié)
vue中 關(guān)于$emit的用法
- 父組件可以使用屬性把數(shù)據(jù)傳給子組件,子組件通過props接受。
- 子組件可以使用 $emit 觸發(fā)父組件的自定義事件。
vm.$emit( event, arg ) //觸發(fā)當(dāng)前實(shí)例上的事件
vm.$on( event, fn );//監(jiān)聽event事件后運(yùn)行 fn;
angular中 關(guān)于emit的用法
- 父組件可以使用屬性把數(shù)據(jù)傳給子組件,子組件通過@input接受。
- 子組件可以使用 Output 和 EventEmitter 觸發(fā)父組件的自定義事件。
父組件
<app-footer (event)="getFooterRun(data)"></app-footer>
子組件
@Output()
private event=new EventEmitter<string>();
/*用 EventEmitter 和 output 裝飾器配合使用 <string>指定類型變量*/
sendParent(){
// outer 相當(dāng)于是事件名稱
this.event.emit(data)
}
<button (event)="sendParent()">通過@Output給父組件廣播數(shù)據(jù)</button>
生命周期函數(shù)
官方文檔:https://www.angular.cn/guide/lifecycle-hooks
生命周期函數(shù)通俗的講就是組件創(chuàng)建、組件更新、組件銷毀的時(shí)候會(huì)觸發(fā)的一系列的方法。
當(dāng) Angular 使用構(gòu)造函數(shù)新建一個(gè)組件或指令后,就會(huì)按下面的順序在特定時(shí)刻調(diào)用這些 生命周期鉤子方法
::: tip
-
一、constructor (非生命周期函數(shù))
-
二、ngOnChanges()
-
三、ngOnInit()
-
四、ngDoCheck()
-
五、ngAfterContentInit()
-
六、ngAfterContentChecked()
-
七、ngAfterViewInit()
-
八、ngAfterViewChecked()
-
九、ngOnDestroy()
::: -
constructor
構(gòu)造函數(shù)中除了使用簡(jiǎn)單的值對(duì)局部變量進(jìn)行初始化 之外,什么都不應(yīng)該做。 (非生命周期函數(shù))
constructor適用場(chǎng)景
constructor中應(yīng)該只進(jìn)行依賴注入而不是進(jìn)行真正的業(yè)務(wù)操作
import { RequestService } from '../../services/request.service';
.......
//使用構(gòu)造注入方式,注入服務(wù)
constructor(public request:RequestService) { }
-
ngOnChanges()
當(dāng) Angular(重新)設(shè)置數(shù)據(jù)綁定輸入屬性時(shí)響應(yīng)。 該 方法接受當(dāng)前和上一屬性值的 SimpleChanges 對(duì)象 當(dāng)被綁定的輸入屬性的值發(fā)生變化時(shí)調(diào)用,首次調(diào)用一 定會(huì)發(fā)生在 ngOnInit() 之前。
當(dāng)被綁定的輸入屬性的值發(fā)生變化時(shí)調(diào)用(父子組件傳值的時(shí)候會(huì)觸發(fā))
-
ngOnInit()
在 Angular 第一次顯示數(shù)據(jù)綁定和設(shè)置指令/組件的輸入屬性之后,初始化指令/組件。
在第一輪 ngOnChanges() 完成之后調(diào)用,只調(diào)用一次。
使用 ngOnInit() 有兩個(gè)原因:
- 在構(gòu)造函數(shù)之后馬上執(zhí)行復(fù)雜的初始化邏輯
- 在 Angular 設(shè)置完輸入屬性之后,對(duì)該組件進(jìn)行準(zhǔn)備。 有經(jīng)驗(yàn)的開發(fā)者會(huì)認(rèn)同組件的構(gòu)建應(yīng)該很便宜和安全。
請(qǐng)求數(shù)據(jù)一般放在這個(gè)里面
-
ngDoCheck()
檢測(cè),并在發(fā)生 Angular 無法或不愿意自己檢測(cè)的變化時(shí)作出反應(yīng)。在每個(gè) Angular 變更檢測(cè)周期中調(diào)用,
ngOnChanges() 和 ngOnInit()之后。
檢測(cè),并在發(fā)生 Angular 無法或不愿意自己檢測(cè)的變化時(shí)作出反應(yīng)
-
ngAfterContentInit()
當(dāng)把內(nèi)容投影進(jìn)組件之后調(diào)用。第一次 ngDoCheck() 之 后調(diào)用,只調(diào)用一次。
當(dāng)把內(nèi)容投影進(jìn)組件之后調(diào)用 -
ngAfterContentChecked()
每次完成被投影組件內(nèi)容的變更檢測(cè)之后調(diào)用。 ngAfterContentInit() 和每次 ngDoCheck() 之后調(diào)用。
-
ngAfterViewInit()
視圖加載完成以后觸發(fā)的方法,初始化完組件視圖及其子視圖之后調(diào)用。第一次 ngAfterContentChecked()之后調(diào)用,只調(diào)用一次。
初始化完組件視圖及其子視圖之后調(diào)用(dom操作放在這個(gè)里面) -
ngAfterViewChecked()
每次做完組件視圖和子視圖的變更檢測(cè)之后調(diào)用。 ngAfterViewInit()和每次 ngAfterContentChecked() 之后 調(diào)用
-
ngOnDestroy()
當(dāng) Angular 每次銷毀指令/組件之前調(diào)用并清掃。在這 兒反訂閱可觀察對(duì)象和分離事件處理器,以防內(nèi)存泄 漏。 在 Angular 銷毀指令/組件之前調(diào)用。
1 父?jìng)髯拥亩环N方式
父
<app-refs [block]="aaa" views="aaa"></app-refs>
ts
public aaa=1;
子組件
@Component({
selector: 'app-refs',
templateUrl: './refs.component.html',
styleUrls: ['./refs.component.less'],
inputs: ['block','v:views'],
})
public block;
public v;
ngOnInit(): void {
console.log(this.block);
console.log(this.v);
}
2 子傳父的另一種方式
父
<app-refs (a)="onEvery($event)" (b)="onFive($event)"></app-refs>
onEvery(e){
console.log(e);
}
onFive(e){
console.log(e);
}
子
@Component({
outputs: ['a', 'c:b']
})
public a = new EventEmitter();
public c = new EventEmitter();
ngOnInit(): void {
this.a.emit('333');
this.c.emit('444');
}
Rxjs 異步數(shù)據(jù)流編程
Rxjs 介紹
參考手冊(cè)
中文手冊(cè)
RxJS 是 ReactiveX 編程理念的 JavaScript 版本。ReactiveX 來自微軟,它是一種針對(duì)異步數(shù)據(jù)流的編程。簡(jiǎn)單來說,它將一切數(shù)據(jù),包括 HTTP 請(qǐng)求,DOM 事件或者普通數(shù)據(jù)等包裝成流 的形式,然后用強(qiáng)大豐富的操作符對(duì)流進(jìn)行處理,使你能以同步編程的方式處理異步數(shù)據(jù), 并組合不同的操作符來輕松優(yōu)雅的實(shí)現(xiàn)你所需要的功能。
RxJS 是一種針對(duì)異步數(shù)據(jù)流編程工具,或者叫響應(yīng)式擴(kuò)展編程;可不管如何解釋 RxJS 其目 標(biāo)就是異步編程,Angular 引入 RxJS 為了就是讓異步可控、更簡(jiǎn)單。
RxJS 里面提供了很多模塊。這里我們主要給大家講 RxJS 里面最常用的 Observable 和 fromEvent。
目前常見的異步編程的幾種方法:
- 回調(diào)函數(shù)
- 事件監(jiān)聽/發(fā)布訂閱
- Promise 是 ES6
- async/await 是 ES7
- Rxjs 是一個(gè) js 庫
Promise 和 RxJS 處理異步對(duì)比
Promise 處理異步:
let promise = new Promise(resolve => {
setTimeout(() => {
resolve("---promisetimeout---");
}, 2000);
});
promise.then(value => console.log(value));
RxJS 處理異步:
import { Observable } from "rxjs";
let stream = new Observable(observer => {
setTimeout(() => {
observer.next("observabletimeout");
}, 2000);
});
stream.subscribe(value => console.log(value));
從上面列子可以看到 RxJS 和 Promise 的基本用法非常類似,除了一些關(guān)鍵詞不同。 Promise 里面用的是 then() 和 resolve(),而 RxJS 里面用的是 next() 和 subscribe()。
從上面例子我們感覺 Promise 和 RxJS 的用法基本相似。其實(shí) Rxjs 相比 Promise 要強(qiáng)大很多。 比如 Rxjs 中可以中途撤回、Rxjs 可以發(fā)射多個(gè)值、Rxjs 提供了多種工具函數(shù)等等。
Rxjs unsubscribe 取消訂閱
Promise 的創(chuàng)建之后,動(dòng)作是無法撤回的。Observable 不一樣,動(dòng)作可以通過 unsbscribe() 方法中途撤回,而且 Observable 在內(nèi)部做了智能的處理.
Promise 創(chuàng)建之后動(dòng)作無法撤回
let promise = new Promise(resolve => {
setTimeout(() => {
resolve("---promisetimeout---");
}, 2000);
});
promise.then(value => console.log(value));
Rxjs 可以通過 unsubscribe() 可以撤回 subscribe 的動(dòng)作
let stream = newObservable(observer => {
let timeout = setTimeout(() => {
clearTimeout(timeout);
observer.next("observabletimeout");
}, 2000);
});
let disposable = stream.subscribe(value => console.log(value));
setTimeout(() => {
//取消執(zhí)行
disposable.unsubscribe();
}, 1000);
Rxjs 訂閱后多次執(zhí)行
如果我們想讓異步里面的方法多次執(zhí)行,比如下面代碼。
這一點(diǎn) Promise 是做不到的,對(duì)于 Promise 來說,最終結(jié)果要么 resolve(兌現(xiàn))、要么 reject (拒絕),而且都只能觸發(fā)一次。如果在同一個(gè) Promise 對(duì)象上多次調(diào)用 resolve 方法, 則會(huì)拋異常。而 Observable 不一樣,它可以不斷地觸發(fā)下一個(gè)值,就像 next() 這個(gè)方法的 名字所暗示的那樣。
let promise = new Promise(resolve => {
setInterval(() => {
resolve("---promisesetInterval---");
}, 2000);
});
promise.then(value => console.log(value));
Rxjs
let stream =
new Observable() <
number >
(observer => {
let count = 0;
setInterval(() => {
observer.next(count++);
}, 1000);
});
stream.subscribe(value => console.log("Observable>" + value));
Angualr6.x 之前使用 Rxjs 的工具函數(shù) map,filter
注意:Angular6 以后使用以前的 rxjs 方法,必須安裝 rxjs-compat 模塊才可以使用 map、 filter 方法。
angular6 后官方使用的是 RXJS6 的新特性,所以官方給出了一個(gè)可以暫時(shí)延緩我們不需要修改 rsjx 代碼的辦法。
npm install rxjs-compat
import {Observable} from 'rxjs';
import 'rxjs/Rx';
let stream =
new Observable() <any>
(observer => {
let count = 0;
setInterval(() => {
observer.next(count++);
}, 1000);
});
stream
.filter(val => val % 2 == 0)
.subscribe(value => console.log("filter>" + value));
stream
.map(value => {
return value * value;
})
.subscribe(value => console.log("map>" + value));
Angualr6.x 以后 Rxjs6.x 的變化以及使用
RXJS6 改變了包的結(jié)構(gòu),主要變化在 import 方式和 operator 上面以及使用 pipe()
import {Observable} from 'rxjs';
import {map,filter} from 'rxjs/operators';
let stream = new Observable<any>(observer => {
let count = 0;
setInterval(() => {
observer.next(count++);
}, 1000);
});
stream
.pipe(filter(val => val % 2 == 0))
.subscribe(value => console.log("filter>" + value));
stream
.pipe(
filter(val => val % 2 == 0),
map(value => {
return value * value;
})
)
.subscribe(value => console.log("map>" + value));
Angular 中的數(shù)據(jù)交互(get,post)
-
- HttpClientModule
-
- axios
Angular get 請(qǐng)求數(shù)據(jù)
Angular5.x 以后 get、post 和和服務(wù)器交互使用的是 HttpClientModule 模塊
- 在 app.module.ts 中引入 HttpClientModule 并注入
import {HttpClientModule} from '@angular/common/http'
imports: [ BrowserModule, HttpClientModule ]
- 在用到的地方引入 HttpClient 并在構(gòu)造函數(shù)聲明
import {HttpClient} from "@angular/common/http";
constructor(public http:HttpClient) { }
- get 請(qǐng)求數(shù)據(jù)
var api = "http://localhost:3000/info";
this.http.get(api).subscribe(response => {
console.log(response);
});
Angular post 提交數(shù)據(jù)
Angular5.x 以后 get、post 和和服務(wù)器交互使用的是 HttpClientModule 模塊。
- 在 app.module.ts 中引入 HttpClientModule 并注入
import {HttpClientModule} from '@angular/common/http';
imports: [ BrowserModule, HttpClientModule ]
- 在用到的地方引入 HttpClient、HttpHeaders 并在構(gòu)造函數(shù)聲明 HttpClient
import {HttpClient,HttpHeaders} from "@angular/common/http";
constructor(public http:HttpClient) { }
- post 提交數(shù)據(jù)
const httpOptions={
headers:newHttpHeaders({'Content-Type':'application/json'})
};
var api="http://127.0.0.1:3000/doLogin";
this.http.post(api,{username:'張三',age:'20'},httpOptions).subscribe(response=>{
console.log(response);
});
axios 請(qǐng)求數(shù)據(jù)
-
安裝 axios
yarn add axios -D -
用到的地方引入 axios
import axios from ‘a(chǎn)xios’; -
看文檔使用
axios.get('/user?ID=12345')
.then(function(response){
//handle success
console.log(response);
})
.catch(function(error){
//handle error
console.log(error);
})
.then(function(){
//always executed
});
Angular 中的路由
- 命令創(chuàng)建項(xiàng)目
ng new ng-demo --skip-install
- 創(chuàng)建需要的組件
ng g component components/home
ng g component components/news
ng g component components/newscontent
- 找到 app-routing.module.ts 配置路由
引入組件
import { HomeComponent } from './components/home/home.component';
import { NewsComponent } from './components/news/news.component';
import { ProductComponent } from './components/product/product.component';
配置路由
const routes: Routes = [
{path: 'home', component: HomeComponent},
{path: 'news', component: NewsComponent},
{path:'product', component:ProductComponent },
{path: '*', redirectTo: '/home', pathMatch: 'full' }
];
- 找到 app.component.html 根組件模板,配置 router-outlet 顯示動(dòng)態(tài)加載的路由
<h1>
<a routerLink="/home">首頁</a>
<a routerLink="/news">新聞</a>
</h1>
<router-outlet></router-outlet>
routerLink 跳轉(zhuǎn)頁面默認(rèn)路由
<a routerLink="/home">首頁</a>
<a routerLink="/news">新聞</a>
//匹配不到路由的時(shí)候加載的組件 或者跳轉(zhuǎn)的路由
{
path: '**', /*任意的路由*/
// component:HomeComponent
redirectTo:'home'
}
routerLinkActive
設(shè)置 routerLink 默認(rèn)選中路由
<h1>
<a routerLink="/home" routerLinkActive="active">
首頁
</a>
<a routerLink="/news" routerLinkActive="active">
新聞
</a>
</h1>
<h1>
<a [routerLink]="[ '/home' ]" routerLinkActive="active">首頁</a>
<a [routerLink]="[ '/news' ]" routerLinkActive="active">新聞</a>
</h1>
動(dòng)態(tài)路由
問號(hào)傳參
跳轉(zhuǎn)方式,頁面跳轉(zhuǎn)或js跳轉(zhuǎn)
問號(hào)傳參的url地址顯示為 …/list-item?id=1
頁面跳轉(zhuǎn)
queryParams屬性是固定的
<a [routerLink]="['/list-item']" [queryParams]="{id:item.id}">
<span>{{ item.name }}</span>
</a>
//js跳轉(zhuǎn)-router為ActivatedRoute的實(shí)例
import { Router } from '@angular/router';
constructor(private router: Router) {}
this.router.navigate(['/newscontent'],{
queryParams:{
name:'laney',
id:id
},
skipLocationChange: true
//可以不寫,默認(rèn)為false,設(shè)為true時(shí)路由跳轉(zhuǎn)瀏覽器中的url會(huì)保持不變,傳入的參數(shù)依然有效
});
獲取參數(shù)方式
import { ActivatedRoute } from '@angular/router';
constructor(public route:ActivatedRoute) { }
ngOnInit() {
this.route.queryParams.subscribe((data)=>{
console.log(data);
})
}
路徑傳參
路徑傳參的url地址顯示為 …/list-item/1
<!-- 頁面跳轉(zhuǎn) -->
<a [routerLink]="['/list-item', item.id]">
<span>{{ item.name }}</span>
</a>
js跳轉(zhuǎn)-router為ActivatedRoute的實(shí)例
this.router.navigate(['/list-item', item.id]);
路徑配置:{path: 'list-item/:id', component: ListItemComponent}
獲取參數(shù)方式
this.route.params.subscribe(
param => {
this.id= param['id'];
}
)
父子路由
- 創(chuàng)建組件引入組件
import { WelcomeComponent } from './components/home/welcome/welcome.component';
import { SettingComponent } from './components/home/setting/setting.component';
- 配置路由
{
path:'home',
component:HomeComponent,
children:[{
path:'welcome',
component:WelcomeComponent
},{
path:'setting',
component:SettingComponent
},
{path: '**', redirectTo: 'welcome'}
]
},
- 父組件中定義router-outlet
<router-outlet></router-outlet>
Angular 內(nèi)置模塊
[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來直接上傳(img-IZLVMIXL-1651495956879)(/pic/01.png)]
Angular 自定義模塊
當(dāng)我們項(xiàng)目比較小的時(shí)候可以不用自定義模塊。但是當(dāng)我們項(xiàng)目非常龐大的時(shí)候把所有的組件都掛載到根模塊里面不是特別合適。所以這個(gè)時(shí)候我們就可以自定義模塊來組織我們的項(xiàng)目。并且通過 Angular自定義模塊可以實(shí)現(xiàn)路由的懶加載。
ng g module mymodule
[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來直接上傳(img-PiW6qTXC-1651495956880)(/pic/02.png)]
新建一個(gè) user 模塊
ng g module module/user
新建一個(gè) user 模塊下的根組件
ng g component module/user
新建一個(gè) user 模塊下的 address,order,profile 組件
ng g component module/user/components/address
ng g component module/user/components/order
ng g component module/user/components/profile
如何在根模塊掛載 user 模塊呢?
在 app 根組件的模板文件 app.component.html 里引用 user 組件會(huì)報(bào)錯(cuò)
需要如下處理才可以被訪問
- 在 app.module.ts 引入模塊
[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來直接上傳(img-9CqWx5BE-1651495956882)(/pic/配置模塊01.png)]
-
user 模塊暴露出 要被外界訪問到的組件
[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來直接上傳(img-r6rdj5It-1651495956883)(/pic/配置模塊02.png)] -
在根模板 app.component.html 里引入
<app-user></app-user>
如果需要在根組件里直接 使用 app-address 組件,也是需要先在 user 模塊 user.module.ts 暴露
/暴露組件 讓其他模塊里面可以使用暴露的組件/
exports:[UserComponent,AddressComponent]
創(chuàng)建 user 模塊下的服務(wù)
-
創(chuàng)建
ng g service module/user/services/common -
在 user 模塊引入服務(wù)
[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來直接上傳(img-ygkZwBhQ-1651495956883)(/pic/service.png)]
配置路由實(shí)現(xiàn)模塊懶加載
[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來直接上傳(img-CE56DjLF-1651495956884)(/pic/03.png)]
創(chuàng)建模塊:
ng g module module/user --routing
ng g module module/article --routing
ng g module module/product --routing
創(chuàng)建組件:
ng g component module/user
ng g component module/user/components/profile
ng g component module/user/components/order
ng g component module/article
ng g component module/article/components/articlelist ng g component module/article/components/info
ng g component module/product
ng g component module/product/components/plist
ng g component module/product/components/pinfo
angular配置懶加載
在angular中路由即能加載組件又能加載模塊,而我們說的懶加載實(shí)際上就是加載模塊,目前還沒有看到懶加載組件的例子。
加載組件使用的是component關(guān)鍵字
加載模塊則是使用loadChildren關(guān)鍵字
[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來直接上傳(img-xClo5WMU-1651495956885)(/pic/03.png)]
1. 在app文件夾下 新建 app-routing.module.ts
內(nèi)容如下:
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }
forRoot是用在根模塊加載路由配置,
而forChild是用在子模塊加載路由配置。
注意:需要在根模板 app.module.ts里導(dǎo)入AppRoutingModule模塊
import { AppRoutingModule } from './app-routing.module';
...
imports: [
AppRoutingModule,
]
2. 在子模塊里配置路由
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
// import {ArticleComponent} from './article.component';
const routes: Routes = [
// {
// path:'',
// component:ArticleComponent
// }
];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
})
export class ArticleRoutingModule { }
也可以在新建項(xiàng)目的時(shí)候 就把路由的模塊加上,可以省去上面的配置
在 article模塊的 article-routing.module.ts配置路由
import {ArticleComponent} from './article.component';
const routes: Routes = [
{
path:'',
component:ArticleComponent
}
];
3. 在app的路由模塊進(jìn)行配置路由
const routes: Routes = [
{
path:'article',
//寫法一:
loadChildren:'./module/article/article.module#ArticleModule'
//寫法二
// loadChildren: () => import('./module/user/user.module').then( m => m.UserModule)
},
// {
// path:'user',loadChildren:'./module/user/user.module#UserModule'
// },
// {
// path:'product',loadChildren:'./module/product/product.module#ProductModule'
// },
{
path:'**',redirectTo:'article'
}
];
如果在之前新建模塊的時(shí)候沒有加上–routing,,需要配置模塊的路由
product模塊
product的路由:module\product\product-routing.module.ts
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import {ProductComponent} from './product.component';
const routes: Routes = [
{
path:'',
component:ProductComponent
}
];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
})
export class ProductRoutingModule { }
product的模塊:
import { ProductRoutingModule } from './product-routing.module';
imports: [
ProductRoutingModule
],
user模塊
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import {UserComponent} from './user.component';
const routes: Routes = [
{
path:'',
component:UserComponent
}
];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
})
export class UserRoutingModule { }
user的模塊
import {UserRoutingModule} from './user-routing.module'; +
imports: [
UserRoutingModule +
],
RouterModule.forRoot() 和 RouterModule.forChild()
RouterModule對(duì)象為提供了兩個(gè)靜態(tài)的方法:forRoot()和forChild()來配置路由信息。
RouterModule.forRoot()方法用于在主模塊中定義主要的路由信息,RouterModule.forChild()與 Router.forRoot()方法類似,但它只能應(yīng)用在特性模塊中。
即根模塊中使用forRoot(),子模塊中使用forChild()。
配置子路由
- 在商品模塊的路由product-routing.module.ts 配置子路由
import { PlistComponent } from './components/plist/plist.component';
import { CartComponent } from './components/cart/cart.component';
import { PinfoComponent } from './components/pinfo/pinfo.component';
const routes: Routes = [
{
path:'',
component:ProductComponent,
children:[
{path:'cart',component:CartComponent},
{path:'pcontent',component:PinfoComponent}
]
},
{path:'plist',component:PlistComponent}
];
- 在商品模塊的模板product.component.html 添加router-outlet
<router-outlet></router-outlet>
- 在頁面app.component.html添加菜單,方便跳轉(zhuǎn)
<a [routerLink]="['/product']">商品模塊</a>
<a [routerLink]="['/product/plist']">商品列表</a>
Ngxs 狀態(tài)管理
https://www.jianshu.com/p/f343b8bca096
https://blog.csdn.net/roamingcode/article/details/84568140
https://blog.csdn.net/fen747042796/article/details/74840844
問題: The pipe ‘a(chǎn)sync’ could not be found?
@NgModule 的申明沒有被子模塊繼承, 如果你在子模塊中需要管道 pipe , directives, components, 在子模塊里應(yīng)該 再次導(dǎo)入需要的模塊
這個(gè) pipes 都是來自于 CommonModule
import { CommonModule } from ‘@angular/common’;
import { CommonModule } from '@angular/common';
@NgModule({
imports: [ CommonModule ]
})
class ArticleModule {}
為什么在 app.component組件可以工作, 是因?yàn)?你已經(jīng)導(dǎo)入了 BrowserModule ,BrowserModule又重新導(dǎo)出了 CommonModule, 所以只需要導(dǎo)入 BrowserModule 就間接的導(dǎo)入了 CommonModule
同樣值得注意的是,CommonModule也有核心指令,比如ngFor和ngIf。因此,如果您有一個(gè)使用這些功能的功能模塊,則還需要將CommonModule導(dǎo)入該模塊文章來源:http://www.zghlxwxcb.cn/news/detail-780785.html
[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來直接上傳(img-VQRPn0V8-1651495956887)(/pic/子模塊.png)]文章來源地址http://www.zghlxwxcb.cn/news/detail-780785.html
到了這里,關(guān)于angular框架簡(jiǎn)介基礎(chǔ)與使用(全文2w8字)前端框架angular的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!