Angular概念和TypeScript基础语法

什么是Angular

Angular是构建用户界面的JavaScript框架;由 Google 开发和维护,主要被用来开发单页面应用程序。它的创新之处在于,通过数据绑定和依赖注入减少了大量代码,而这些都在浏览器端通过JavaScript实现,能够和任何服务器端技术完美结合。

Angular的出众之处

  • 构建一个CRUD应用时可能用到的所有技术:数据绑定、基本模板指令、表单验证、路由、深度链接、组件重用、依赖注入。
  • 可测试性:单元测试、端到端测试、模拟对象(mocks)、测试工具。
  • 拥有一定目录结构和测试脚本的种子应用。

Angular脚手架

Angular CLI 是 Angular 官方开发的一个类似于 Vue CLI 的脚手架开发工具,它帮我们集成了 webpack 打包、开发服务器、单元测试、自动编译、部署等功能特性。

  • 全局安装脚手架
cnpm i -g @angular/cli
ng --version
  • 安装失败解决方案

在 Windows 平台上安装 @angular/cli 会报很多 error,那是因为 @angular/cli 在 Windows 平台上面依赖 Python 和 Visual Studio 环境,而很多开发者的机器上并没有安装这些东西

  1. 安装Node.js
  2. 安装 npm,npm 会随着 Node 的安装被一起安装
  3. 安装 Python
  4. 安装 C++ 编译工具npm install --global --production windows-build-tools
  5. 推荐使用 cnpm 进行安装,可以非常有效地避免撞墙cnpm i -g cnpm --registry=https://registry.npm.taobao.org
  • 查看命令ng help
    命令
  • 创建一个项目ng new my-first-project打开项目cd my-first-project,启动项目ng serve,或则自动打开ng serve --open

各个文件夹的解读

图解解释

核心概念

一门框架都有它的精髓所在;任何一个成功的框架都有自己独创的 “概念模型”,或者叫 “核心价值” 也可以。比如,express框架可以设置中间件来响应 HTTP 请求;定义了路由表用于执行不同的 HTTP 请求动作;可以通过向模板传递参数来动态渲染 HTML 页面。比如,React的虚拟Dom和Diff算法;比如,jQuery的$…Angular的核心模块:

组件

每个 Angular 应用都至少有一个组件,也就是根组件,它会把组件树和页面中的 DOM 连接起来。 每个组件都会定义一个类,其中包含应用的数据和逻辑,并与一个 HTML 模板相关联,该模板定义了一个供目标环境下显示的视图。

  1. 分治:因为有了组件之后,我们可以把各种逻辑封装在组件内部,避免混在一起
  2. 复用:把逻辑封装在组件内部,封装成组件之后不仅可以在项目内部复用,而且可以沉淀下来跨项目复用
模块

Angular 应用是模块化的,它拥有自己的模块化系统,称作 NgModule。 一个 NgModule 就是一个容器,用于存放一些内聚的代码块,这些代码块专注于某个应用领域、某个工作流或一组紧密相关的功能。 它可以包含一些组件、服务提供商或其它代码文件,其作用域由包含它们的 NgModule 定义。 它还可以导入一些由其它模块中导出的功能,并导出一些指定的功能供其它 NgModule 使用。

  1. NgModule(模块)是组织业务代码的利器,按照你自己的业务场景,把组件、服务、路由打包到模块里面,形成一个个的积木块,然后再用这些积木块来搭建出高楼大厦。
模板

模板会把 HTML 和 Angular 的标记(markup)组合起来,这些标记可以在 HTML 元素显示出来之前修改它们。

  1. 组件是用来封装对视图的操作的,而我们的所谓的视图其实也就是常规的 HTML 模板.
  2. 视图通常会分层次进行组织,让你能以 UI 分区或页面为单位进行修改、显示或隐藏。
元数据

NgModule 是一个带有 @NgModule() 装饰器的类。@NgModule() 装饰器是一个函数,它接受一个元数据对象,该对象的属性用来描述这个模块。

  1. 元数据告诉 Angular 如何处理组件类。
指令和数据绑定

指令会提供程序逻辑,而绑定标记会把你应用中的数据和 DOM 连接在一起。

  1. 事件绑定让你的应用可以通过更新应用的数据来响应目标环境下的用户输入。
  2. 属性绑定让你将从应用数据中计算出来的值插入到 HTML 中。
  3. 通过特殊的 {{}} 语法将数据绑定到 DOM 元素,当数据改变的时候会影响视图的更新。
  4. [(ngModel)]表单控件双向绑定指令,ngFor 循环指令…
服务和注入依赖

对于与特定视图无关并希望跨组件共享的数据或逻辑,可以创建服务类。 服务类的定义通常紧跟在 “@Injectable()” 装饰器之后。该装饰器提供的元数据可以让你的服务作为依赖被注入到客户组件中。

扫描二维码关注公众号,回复: 6399240 查看本文章
  1. “依赖注入”是提供类的新实例的一种方式,还负责处理好类所需的全部依赖。大多数依赖都是服务。 Angular 使用依赖注入来提供新组件以及组件所需的服务。
  2. 服务是一个广义范畴,包括值、函数、或应用所需的功能。说白了;服务就是针对某个单一或系统功能的封装(最典型的一个服务就是 Http 服务);

组件(src文件下的app)

组件的定义(app.component.ts)
import { Component } from '@angular/core';
@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.less']
})
export class AppComponent {
  title = 'project';
}
  1. @component这是一个Decorator(装饰器);其作用类似于 Java 里面的注解。通俗解释:创建一个组件,附上一些行为。
  2. selector:组件的标签名,外部使用者可以这样来使用这个组件:。默认情况下,ng 命令生成出来的组件都会带上一个 app 前缀,如果你不喜欢,可以在 angular.json 里面修改 prefix 配置项,设置为空字符串将会不带任何前缀。
  3. templateUrl引入外部的HTML模板;如果你想直接编写内联模板;可以使用template;支持es6引入的模板字符串写法
  4. styleUrls引用外部的css样式文件;这是一个数组;也就意味着引用多个文件。
  5. export class AppComponent:这是 ES6 里面引入的模块和 class 定义方式。

TypeScript

TypeScript是JavaScript的强类型版本。然后在编译期去掉类型和特有语法,生成纯粹的JavaScript代码。由于最终在浏览器中运行的仍然是JavaScript,所以TypeScript并不依赖于浏览器,所以不会有兼容问题
TypeScript是JavaScript的超集;这意味着它支持所有的JavaScript语法;并在此之上对JavaScript添加了一些扩展;,如 class / interface / module 等。这样会大大提升代码的可阅读性。
和 JavaScript 若类型不同,TypeScript 这种强类型语言最大的优势在于静态类型检查,可以在代码开发阶段就预知一些低级错误的发生。

  1. 一种类似于 JavaScript 的语言,在 JavaScript 的基础之上增加了类型,同时增强了 JavaScript 部分语法功能
  2. 遵循 EcmaScript 6 标准规范
  3. 由微软开发
  4. Angular 2 框架采用 TypeScript 编写
  5. 背后有微软和谷歌两大公司的支持
  6. TypeScript 可以编译成 JavaScript 从而在支持 JavaScript 的环境中运行
  7. TypeScript 和 JavaScript 的关系就好比 less 和 css 的关系

搭建 TypeScript 开发环境

  1. 在线测试编译环境 compiler
  2. 本地开发编译环境
cnpm i typescript -g
新建 greeter.ts 
新建 greeter.ts 并写入以下内容:

TypeScript语法

// 接口(interface)
interface Person {
    firstname: string;
    lastname: string;
}
function greeter(person:Person) {
    return "Hello,"+person.firstname+person.lastname
}
let user = {
    firstname: '111',
    lastname: '222'
}
document.body.innerHTML = greeter(user)
// 类(Class)
class Student{
    fullname: string;
    constructor(public firstname:string,public lastname:string) {
        this.fullname = firstname+lastname
    }
}
console.log(new Student('1111','222'))

使用最小特权原则,所有变量除了你计划去修改的都应该使用const。 基本原则就是如果一个变量不需要对它写入,那么其它使用这些代码的人也不能够写入它们,并且要思考为什么会需要对这些变量重新赋值。 使用 const也可以让我们更容易的推测数据的流动。

1.var:可重复声明和预解析
2.let:块级作用域,在同一块中不能重复声明
3. const:声明同时必须赋值,是一个常量,即声明不可改变(对象可以修改)

// 数据类型
// 布尔值
let isDone: boolean = false;
// 数字
let num: number = 12;
// 字符串:支持换行,支持内嵌表达式
let nickname: string = 'GenG'
let str: string = `我是:${nickname}`
//1. 数组:可以在元素类型后面接上`[]`
let numArr: number[] = [1, 2, 3]
//2. 数组:使用数组泛型
let strArr: Array<string> = ['1','2','3']
// 元组:允许一个已知元素数量和类型的数组,各元素类型不必相同
let x: [string, number] = ['hello', 10]
// Object:允许赋任意值,但是不能调用任意方法,即便它真的有
let obj = {
    firstNum: 'string'
}
// 我们会想要为那些在编程阶段还不清楚类型的变量指定一个类型,可以使用 any类型来标记这些变量,表示任何类型
let notSure: any = 4
notSure = 'string'
// void类型像是与any类型相反,它表示没有任何类型。 当一个函数没有返回值时,你通常会见到其返回值类型是 void:
function warnSure(): void{
    alert('msg')
}
warnSure()
// 声明一个void类型的变量:它只赋值给null或则undefined
let unusable: void = null;
// null和undefined:默认情况下null和undefined是所有类型的子类型。然而,当你指定了--strictNullChecks 标记,null 和 undefined 只能赋值给 void 和它们各自。 这能避免 很多常见的问题。许在某处你想传入一个 string或null或undefined,你可以使用联合类型string | null | undefined。
let u: undefined = undefined;

类型推断:有时候你会遇到这样的情况,你会比TypeScript更了解某个值的详细信息。 通常这会发生在你清楚地知道一个实体具有比它现有类型更确切的类型。通过类型断言这种方式可以告诉编译器,“相信我,我知道自己在干什么”。 类型断言好比其它语言里的类型转换,但是不进行特殊的数据检查和解构。 它没有运行时的影响,只是在编译阶段起作用。 TypeScript会假设你,程序员,已经进行了必须的检查。

// 使用尖括号实现类型断言
let someValue: any = '111111';
console.log(<string>someValue.length)
// 使用as语法进行类型断言
let someValue = '计算出我的长度'
let len:number = (someValue as string).length

两种形式是等价的。 至于使用哪个大多数情况下是凭个人喜好;然而,当你在TypeScript里使用JSX时,只有 as语法断言是被允许的。

在TypeScript里,接口的作用就是为这些类型命名和为你的代码或第三方代码定义契约。

// 只读属性:一些对象属性只能在对象刚刚创建的时候修改其值。
interface Point {
    readonly x: number;
    readonly y: number;
}
let p1: Point = { x: 10, y: 20 }
// p1.x = 20 //error
// 可选属性:接口里的属性不全都是必需的。
interface SquareConfig {
    color?: string;
    width?: number
}
function createSquare(config: SquareConfig) {
    return config;
}
console.log(createSquare({color:'#ccc'}))

解构赋值

// 数组解构
let arr: number[] = [1, 2]
let [first, second] = arr
console.log(first) // 1
// 函数参数解构赋值
function f([one, two]:[string,number]) {
        console.log(one)// '111'
        console.log(two)// 22
}
f(['111', 22])
// 解构剩余参数
let [num1, ...rest] = [1, 23, 55, 66]
console.log(rest) //[23, 55, 66]
// 跳过解构赋值
let [n1, , n3] = [1, 2, 3]
console.log(n3) //3
// 数组解构,你可以用没有声明的赋值:
let a: number, b: Number;
({ a, b } = {
    a: 123,
    b:456
})
console.log(a) //123
// 可以在对象里使用 ... 语法创建剩余变量
let obj = {
    age: '123',
    gender: 'boy',
    g: '12'
}
let { age, ...rest } = obj
console.log(rest) // {g: "12"gender: "boy"}
// 属性解构重命名
let { age: newValue1, gender: newValue2 } = obj
console.log(newValue1) //123
// 解构赋值用于函数声明
type C = {
    a: number,
    b: string
}
function f({a, b}:C):void{
    
}
// 参数及返回值类型
function sum(a: number, b: number):number {
    return a+b
}
// 可选参数
function add(a?: number, b?: string):number {
    return a + 10;
}
// 默认参数
function sum1(n1: number,n2:number = 20) {
    return n1+n2
}
// 剩余参数
function sum2(...args: number[]) {
    console.log(args)
}
console.log(sum2(1,23,55))

Angular参考文档

Angular中文官方文档
AngularJS中文网
Angular 7.0入门
如何评价TypeScript
TypeScript中文文档
es6入门

先到这

猜你喜欢

转载自blog.csdn.net/weixin_41105030/article/details/89507883