Typescript详解
- typescript由微软开发的一款开源编程语言。
- ts是jacascript的超集,遵循ES6,ES5规范,ts扩展了js的语法。
- ts更像后端java,c#这样的面向对象的语言,可以让js开发大型的企业项目,
- 谷歌也大力支持ts的推广,谷歌的angular2.x就是基于ts语法开发的
- 最新的Vue,React也继承ts
- Nodejs框架Nestjs,midway中用的就是ts语法.
基础配置
安装:npm i -g typescript
验证是否安装成功:tsc -v
Version 4.4.3
编译ts:tsc index.ts(需要编译的ts文件)
ts开发工具 vscode自动编译ts
- 创建tsconfig.json文件
tsc --init 生成配置文件
只改tsconfig:outdir:'./js' - 自动生成js
vscode-->终端-->运行任务-->typescript-->tsc:监视
一、ts中的类型
ts中为了是编写的代码更加规范,更有利于维护,增加了类型校验。
类型赋值错误会报错,
主要类型有:
类型 | 名称 | 解释 | 写法 |
---|---|---|---|
布尔类型 | boolean | true/false | var flag:boolean=true |
数值类型 | number | 整数/小数 | var num:number=123 |
字符串类型 | string | 字符串 | var str:string='123' |
数组类型 | array | 数组 | let arr:number[]=[1,2,3](只能放number类型)/let arr:Array=[1,2,3](只能放number类型,泛型定义)/ |
元组类型 | tuple | 数组的一种可以指定数组里每项类型 | let arr:[string,number,boolean]=['ww',123,true] |
枚举类型 | enum | enum 枚举名称{标识符[=整形常数]...} | enum Flag{success:1,err:-1},var f:Flag=Flag.err enum Color={red,blue,orage} ,var c:Color=Color.blue //c==1 |
任意类型 | any | 任意的值 | let num:any='123' |
null、undefined | 其他类型子类型 | var num:number | |
void类型 | void | 没有任何类型,一般用于函数没有返回值 | function run():void {} |
其他类型 | never | 包括null,undefined子类型,代表从不会出现的值 | never的变量只能被never类型赋值 |
二、函数定义
ES5函数定义
函数声明
function run() {
return 'run'
}
匿名函数
var run2 = function () { }
ts函数定义方法
1-函数声明
function run1(): string {
return 'aa'
}
2-匿名函数
var fun2 = function (): number {
return 123
}
3-传参
function getInfo(name: string, age: number): string {
return `${name}++${age}`
}
console.log(getInfo('asd', 22))
4-无返回值
```function run3(): void { }````
ts方法的可选参数
ES5方法的实参和形参可以不一样,ts中必须一样,如果不一样需要配置可选参数
注意:可选参数必须配置到参数最后面,用?表示可选
function getInfos(name: string, age?: number): string {
return `${name}++${age}`
}
默认参数
es5里面没法设置默认参数,es6和ts找那个可以设置默认参数
默认参数可以不传,类似于可选参数
function getInfo1(name: string, age: number = 20): string {
return `${name}++${age}`
}
剩余参数
1-改进前写法
function sum(a: number, b: number, c: number, d: number): number {
return a + b + c + d
}
2-改进后
三点运算符 接收新传过来的值
function sum1(...arr: number[]): number {
var sum = 0
for (let i = 0; i < arr.length; i++) {
sum += arr[i]
}
return sum
}
alert(sum1(1, 2, 3, 4))
另一种
function sum2(a: number, ...arr: number[]): number {
var sum = 0
for (let i = 0; i < arr.length; i++) {
sum += arr[i]
}
return a + sum
}
alert(sum2(1, 2, 3, 4))
函数重载
java中方法的重载,:两个或以上同名函数,但他们参数不一样,这是会出现函数重载情况
ts中的从在,通过为一个函数提供多个函数类型定义来实现多种功能的目的
ts为了箭筒es5和es6从在写法和java中有区别
es5中出现同名方法,下面的会替换上面的方法
ts重载
function getcon(name: string): string;
function getcon(age: number): number;
function getcon(name: string,age: number): string;
function getcon(str: any,age?:number): any {
if (typeof str == 'string') {
return '姓名' + str
} else {
return '年龄' + str
}
}
三、对象的继承
es5继承
es5里面的构造函数
function Person() {
this.name = '张珊'
this.age = 20
this.run = function () {
}
}
原型链上的属性会被多个实例共享,构造函数不会
function Person() {
this.name = '张珊'
this.age = 20
this.run = function () {
}
}
Person.prototype.sex = '男'
Person.prototype.work = function () {
console.log(this.name)
}
Person.getInfo = function () {
// 静态方法
}
var p = new Person()
p.work()
// 调用静态方法
Person.getInfo()
构造函数与原型链增加方法
function Person() {
this.name = '张珊'
this.age = 20
this.run = function () { }
}
// 原型链上的属性会被多个实例共享,构造函数不会
Person.prototype.sex = '男'
Person.prototype.work = function () {
console.log(this.name)
}
Person.getInfo = function () {
// 静态方法
}
var p = new Person()
p.work()
类里面的静态方法
function Person() {
this.name = '张珊'
this.age = 20
}
// 定义静态方法
Person.getInfo = function () {
}
var p = new Person()
// 调用静态方法
Person.getInfo()
es5继承
原型链+对象冒充function Person(age) {
this.name = '张珊'
this.age = age
}
Person.prototype.sex = '男'
Person.prototype.work = function () {
console.log(this.name)
}
var p = new Person(18)
// 对象冒充继承---不可以继承原型链的属性和方法
function Web(){
Person.call(this)
} // 原型链继承-----实例化后没法给父类传参
Web.prototype=new Person()
var son=new Web()
ts继承
1、ts定义类
class Person {
name: string; //属性 省略了public关键词
constructor(n: string) {
this.name = n
}//构造函数,实例化类的时候触发的方法
run(): void { }
}
var p = new Person('aa')
p.run()
2、ts中实现继承
关键字:extends,super
子类与父类有相同方法,子类优先级更高
class Person1 {
name: string; //属性 省略了public关键词
constructor(n: string) {
this.name = n
}//构造函数,实例化类的时候触发的方法
run(): string {
return `${this.name}是`
}
}
class Webs extends Person1 {
constructor(name: string) {
super(name)//类似于初始化父类构造函数
}
work() { }
}
var w = new Webs('李四')
3、ts类里面的修饰符
ts里面定义属性的时候给我们提供了三种修饰符
public :公有:在类里面,子类,类外面都可以访问
protected :保护类型:在类里面,子类都可以访问,类外面不可以访问
private:私有:在类里面可以访问,子类,类外面都不可以访问
属性不加修饰符默认公有public
class Person2 {
name: string; //属性 省略了public关键词
private age: number
constructor(n: string, a: number) {
this.name = n
this.age = a
}//构造函数,实例化类的时候触发的方法
run(): string {
return `${this.name}是`
}
}
4、静态属性 静态方法
es5里面的
function Person(){}
Person.run2=function(){}//静态方法
ts里面的
静态方法无法调用类里面的属性,可以调用静态属性
class Person3 {
static sex = 'nam'//静态属性
public name: string
constructor(name: string) {
this.name = name
}
run() { }
static prient() {console.log(this.sex,Person3.sex) }//静态方法
}
var p = new Person3('11')
Person3.prient()//静态方法调用
5、多态
父类定义一个方法不去实现,让继承它的子类去实现,每个子类有不同的表现
多态属于继承的一种表现
class Animal{
name:string
constructor(name:string){
this.name=name
}
eat(){
console.log('吃的方法')
}
}
class Dog extends Animal{
constructor(name:string){
super(name)
}
eat(){
return this.name+'吃肉'
}
}
class Cat extends Animal{
constructor(name:string){
super(name)
}
eat(){
return this.name+'吃鱼'
}
}
6、抽象方法
- ts中的抽象类,他提供其他类集成的基类,不能直接被实例化
- 用abstract关键字定义抽象类和抽象方法,抽象类中的抽象方法不包含具体实现并且必须在派生类中实现
- abstract抽象方法只能放在抽象类里面
- 抽象类的子类必须事项抽象类里面的方法
抽象类和抽象方法用来定义标准
标准:Animal这个类要求他的子类必须包含eat
abstract class Animals{
/**
* name
*/
public name:string
constructor(name:string){
this.name=name
}
abstract eat():any;
}
// 抽象类的子类必须事项抽象类里面的方法
class Dogs extends Animal{
constructor(name:string){
super(name)
}
eat(){
return this.name+'吃肉'
}
}
四、接口
接口的作用:在面向对象的编程中,接口是一种规范的定义,它定义了行为和动作的规范,在程序设计里面,换口起到一种限制和规范的作用。接口定义了某一批央所雷要遵守的现范,接口不关心这些类的内部状态数据,也不关心这些类里方法的实现细节,它只规定这批类里必须提供某些方法,提供这些方法的类就可以满足实际需要。typescrip中的接口类似于java,同时还增加了更灵活的接口类型,包括属性面数、可索引和类
1.属性接口
1、对json的约束
ts自定义方法传入对json进行约束
function prientLabel(labelInfo: { label: string }): void {
}
prientLabel({ name: 'aa' })//错误写法
prientLabel({ label: 'aa' })//正确写法
2、对批量方法进行约束
接口:行为和动作规范,对批量方法进行约束
参数顺序可以不一样,但必须得有
关键词:interface
interface FullName {
firstName: string;//注意;结束
secondName: string;
}
function prientName(name: FullName) {
// 必须传入对象 firstName secoendName
console.log(name.firstName, name.secondName)
}
var obj = { firstName: '1', secondName: 'jj', age: 1 }
prientName(obj)
prientName({ firstName: '1', secondName: 'jj', age: 1 })//传age有问题
接口:可选属性
interface FullNames {
firstName: string;//注意;结束
secondName?: string;
}
案例
interface Config {
type: string;
url: string;
data?: string
dataType: string
}
function ajax(config: Config) {
var xhr = new XMLHttpRequest()
xhr.open(config.type, config.url, true)
xhr.send(config.data)
xhr.onreadystatechange = function () {
if (xhr.readyState == 4 && xhr.status == 200) {
if (config.dataType == 'json') {
JSON.parse(xhr.response)
}
}
}
}
ajax({
type: 'get',
url: 'http://..',
data: '',
dataType: 'json'
})
2.函数类型接口
对传入的参数以及返回值进行约束
加密函数类型接口
interface encrypt {
(ke: string, value: string): string
}
var md5: encrypt = function (key: string, value: string): string {
return key + value
}
3.可索引接口
数组,对象的约束(不常用)
interface UserArr {
[index: number]: string
}
var arr: UserArr = ['11', '22']
interface UserObj {
[index: string]: string
}
var objw: UserObj = { name: '20' }
4.类类型接口
对类进行约束和抽象类有点相似
关键字:implements
interface Animal1 {
name: string;
eat(str: string): void
}
class Dog implements Animal1 {
name: string;
constructor(name: string) {
this.name = name
}
eat() {
}
}
5.接口扩展
接口可以继承接口
interface Animalss {
eat(): void
}
interface Person extends Animalss {
work(): void
}
class Son implements Person {
name: string
constructor(name: string) {
this.name = name
}
eat() { }
work() { }
}
class Progeammer {
name: string
constructor(name: string) {
this.name = name
}
coding() { }
}
class web extends Progeammer implements Person {
constructor(name: string) {
super(name)
}
eat() { }
work() { }
coding() { }
}
五、泛型
- 泛型,软件工程中,我们不仅要创建一致的定义良好的API,同时也要考虑可重用性。 组件不仅能够支持当前的数据类型,同时也能支持未来的数据类型,这在创建大型系统时为你提供了十分灵活的功能。
- 在像C#和Java这样的语言中,可以使用泛型来创建可重用的组件,一个组件可以支持多种类型的数据。这样用户就可以以自己的数据类型来使用组件。
- 通俗理解:泛型就是解决类 接日 方法的复用性、以及对不特定数据类型的支持
普通写法
只能返回string类型的数据
function getData(value:string):string{return value}
返回多种类型的数据 any可以解决这种问题(any放弃了类型检查)
function getData1(value:any):any{return value}
1.泛型定义
- 传入和返回类型相同
- 可以支持不特定的数据类型
- T表示泛型,具体什么类型是调用这个方法的时候决定的
function getData2<T>(value:T):T{return value}
getData2<number>(123)
// getData2<number>(‘kkk’)/* 错误写法 */
2.泛型类
普通写法
class Minclass{
public list:number[]=[]
add(num:number){
this.list.push(num)
}
min():number{
var min=this.list[0]
for (let i = 0; i < this.list.length; i++) {
if(min>this.list[i]){
min=this.list[i]
}
}
return min
}
}
泛型类写法
class Minclass1<T>{
public list:T[]=[]
add(num:T):void{
this.list.push(num)
}
min():T{
var min=this.list[0]
for (let i = 0; i < this.list.length; i++) {
if(min>this.list[i]){
min=this.list[i]
}
}
return min
}
}
var m1=new Minclass1<number>()
3.泛型接口
interface ConfigFn{
(value:string,value2:string):string
}
var setData:ConfigFn=function(val:string,val2:string):string{
return val+val2
}
interface ConfigFn1{
<T>(value:T,value2:T):T
}
var setData1:ConfigFn1=function<T>(val:T,val2:T):T{
return val
}
setData1<string>('123','11')
interface ConfigFn2<T>{
(value:T):T
}
function getData6<T>(val:T):T{
return val
}
var myGetData:ConfigFn2<string>=getData6
myGetData('ll')
案例
class User{
name:string|undefined;
pass:string|undefined
}
class Mysql{
add(user:User):boolean{
return true
}
}
var u=new User()
u.name='zhang'
u.pass='123'
var db=new Mysql()
db.add(u)
泛型封装
class User1{
name:string|undefined;
pass:string|undefined
}
class Mysql1<T>{
add(info:T):boolean{
return true
}
}
var u=new User1()
u.name='zhang'
u.pass='123'
var db1=new Mysql1<User1>()
db1.add(u)
案例
功能:定义一个操作数据库的库支持 Mysql MssqlMongoDb
要求1:Mysql MsSqlMongoDb功能一样都有 add update delete get方法
注意:约束统一的规范、以及代码重用
解决方案:需要约束规范所以要定义接口,需要代码重用所以用到泛型
1、接口:在面向对象的编程中,接口是一种规范的定义,它定义了行为和动作的规范
2、泛型 通俗理解:泛型就是解决类 接口 方法的复用性、
interface DBI<T>{
add(info:T):boolean;
update(info:T,id:number):boolean
delete(id:number):boolean
get(id:number):any[]
}
// 定义一个操作mysql数据库的类
class MysqlDb<T> implements DBI<T>{
add(info: any): boolean {
throw new Error("Method not implemented.")
}
update(info: any, id: number): boolean {
throw new Error("Method not implemented.")
}
delete(id: number): boolean {
throw new Error("Method not implemented.")
}
get(id: number): any[] {
throw new Error("Method not implemented.")
}
}
// 操作用户表 定义一个User类和数据库映射表
class Users{
name:string|undefined
pass:string|undefined
}
var u=new Users()
u.name='00'
u.pass='ii'
var omysql=new MysqlDb<Users>()
omysql.add(u)
六、模块
- 模块的的概念(官方):
- 关于木语的一点说明:请务必注意一点,TypeScript 1.5里木语名已经发生了变化。“内部模块”现在称做“命名空间”。外部模块“现在则简称为“模块#模块在且自身的作用域里执行,而不是在全局作用域里:
- 这意味着定义在一个模块里的变量,因数,类等等在模块外部是不可见的,除非你明确地使用export形式之一导出它们。相反,如果想使用其它模块导出的变量,国数,类,接口等的时候,你必须要导入它们,可以使用 import形式之一。
- 模块的概念(自己理解):
- 我们可以把一些公共的功能单独抽离成一个文件作为一个模块。
- 模块里面的变量 函数 类等默认是私有的,如果我们要在外部访问模块里面的数据(变量、函数、类),我们要要通过export暴露模块里面的数据(变量、团数、类。。》。
- 暴露后我们通过 import 引入模块就可以使用模块里面暴露的数据(变量、函数、类...)。
自定义模块
var dburl='xxx'
export function getData():any[]{
return[{
title:'123'
},{
title:'456'
}]
}
导入
import {getData} from './db'
getData()
export default 默认导出
每个模块都可以有一个default导出,默认导出使用default关键字标记;并且一个模块只能够有一个default导出,需要使用一个特殊的导入形式
七、命名空间
- 在代码量较大的情况下,为了避免各种变量命名相冲突,可将相似功能的函数、类、接口等放置到命名空间内
- 同Java的包、.Net的命名空间一样,TypeScript的命名空间可以将代码包裹起来,只对外暴露需要在外部访问的对象。命名空间内的对象通过export关键字对外暴露。
命名空间和模块的区别
- 命名空间:内部模块,主要用于组织代码,避免命名冲突。
- 模 块:ts的外部模块的简称,侧重代码的复用,一个模块里可能会有多个命名空间。
namespace A{
interface Animal {
name: string;
eat(): void;
}
export class Dog implements Animal {
name: string;
constructor(theName: string) {
this.name = theName;
}
eat() {
console.log(`${this.name} 在吃狗粮。`);
}
}
export class Cat implements Animal {
name: string;
constructor(theName: string) {
this.name = theName;
}
eat() {
console.log(`${this.name} 吃猫粮。`);
}
}
}
namespace B{
interface Animal {
name: string;
eat(): void;
}
export class Dog implements Animal {
name: string;
constructor(theName: string) {
this.name = theName;
}
eat() {
console.log(`${this.name} 在吃狗粮。`);
}
}
export class Cat implements Animal {
name: string;
constructor(theName: string) {
this.name = theName;
}
eat() {
console.log(`${this.name} 在吃猫粮。`);
}
}
}
var c=new B.Cat('小花');
c.eat();
封装:模块化+命名空间
export namespace A{
interface Animal {
name: string;
eat(): void;
}
export class Dog implements Animal {
name: string;
constructor(theName: string) {
this.name = theName;
}
eat() {
console.log(`${this.name} 在吃狗粮。`);
}
}
export class Cat implements Animal {
name: string;
constructor(theName: string) {
this.name = theName;
}
eat() {
console.log(`${this.name} 吃猫粮。`);
}
}
}
import {A} from './modules/animal';
var d=new A.Dog('小黑');
d.eat();
八、装饰器
属性装饰器
装饰器工厂
装饰器定义
- 装饰器:装饰器是一种特殊类型的声明,它能够被附加到类声明,方法,属性或参数上,可以修改类的行为。
- 通俗的讲装饰器就是一个方法,可以注入到类、方法、属性参数上来扩展类、属性、方法、参数的功能。
- 常见的装饰器有:类装饰器、属性装饰器、方法装饰器、参数装饰器
- 装饰器的写法:普通装饰器(无法传参) 、 装饰器工厂(可传参)
- 装饰器是过去几年中js最大的成就之一,已是Es7的标准特性之一
类装饰器
类装饰器:类装饰器在类声明之前被声明(紧靠着类声明)。 类装饰器应用于类构造函数,可以用来监视,修改或替换类定义。 传入一个参数
类装饰器:普通装饰器(无法传参)
function logClass(params:any){
console.log(params);
// params 就是当前类
params.prototype.apiUrl='动态扩展的属性';
params.prototype.run=function(){
console.log('我是一个run方法');
}
}
@logClass
class HttpClient{
constructor(){
}
getData(){
}
}
var http:any=new HttpClient();
console.log(http.apiUrl);
http.run();
类装饰器:装饰器工厂(可传参)
function logClass(params:string){
return function(target:any){
console.log(target);
console.log(params);
target.prototype.apiUrl=params;
}
}
@logClass('http://www.itying.com/api')
class HttpClient{
constructor(){
}
getData(){
}
}
var http:any=new HttpClient();
console.log(http.apiUrl);
类装饰器案例
下面是一个重载构造函数的例子。
装饰器表达式会在运行时当作函数被调用,类的构造函数作为其唯一的参数。
如果类装饰器返回一个值,它会使用提供的构造函数来替换类的声明。
function logClass(target:any){
console.log(target);
return class extends target{
apiUrl:any='我是修改后的数据';
getData(){
this.apiUrl=this.apiUrl+'----';
console.log(this.apiUrl);
}
}
}
@logClass
class HttpClient{
public apiUrl:string | undefined;
constructor(){
this.apiUrl='我是构造函数里面的apiUrl';
}
getData(){
console.log(this.apiUrl);
}
}
var http=new HttpClient();
http.getData();
属性装饰器
属性装饰器表达式会在运行时当作函数被调用,传入下列2个参数:
- 对于静态成员来说是类的构造函数,对于实例成员是类的原型对象。
- 成员的名字。
类装饰器
function logClass(params:string){
return function(target:any){
// console.log(target);
// console.log(params);
}
}
属性装饰器
function logProperty(params:any){
return function(target:any,attr:any){
console.log(target);
console.log(attr);
target[attr]=params;
}
}
@logClass('xxxx')
class HttpClient{
@logProperty('http://itying.com')
public url:any |undefined;
constructor(){
}
getData(){
console.log(this.url);
}
}
var http=new HttpClient();
http.getData();
方法装饰器
它会被应用到方法的 属性描述符上,可以用来监视,修改或者替换方法定义。
方法装饰会在运行时传入下列3个参数:
2. 对于静态成员来说是类的构造函数,对于实例成员是类的原型对象。
2. 成员的名字。
3. 成员的属性描述符。
方法装饰器一
function get(params:any){
return function(target:any,methodName:any,desc:any){
console.log(target);
console.log(methodName);
console.log(desc);
target.apiUrl='xxxx';
target.run=function(){
console.log('run');
}
}
}
class HttpClient{
public url:any |undefined;
constructor(){
}
@get('http://www.itying,com')
getData(){
console.log(this.url);
}
}
var http:any=new HttpClient();
console.log(http.apiUrl);
http.run();
方法装饰器二
function get(params:any){
return function(target:any,methodName:any,desc:any){
console.log(target);
console.log(methodName);
console.log(desc.value);
//修改装饰器的方法 把装饰器方法里面传入的所有参数改为string类型
//1、保存当前的方法
var oMethod=desc.value;
desc.value=function(...args:any[]){
args=args.map((value)=>{
return String(value);
})
oMethod.apply(this,args);
}
}
}
class HttpClient{
public url:any |undefined;
constructor(){
}
@get('http://www.itying,com')
getData(...args:any[]){
console.log(args);
console.log('我是getData里面的方法');
}
}
var http=new HttpClient();
http.getData(123,'xxx');
方法参数装饰器
参数装饰器表达式会在运行时当作函数被调用,可以使用参数装饰器为类的原型增加一些元素数据 ,传入下列3个参数:
- 对于静态成员来说是类的构造函数,对于实例成员是类的原型对象。
- 方法的名字。
- 参数在函数参数列表中的索引。
function logParams(params:any){
return function(target:any,methodName:any,paramsIndex:any){
console.log(params);
console.log(target);
console.log(methodName);
console.log(paramsIndex);
target.apiUrl=params;
}
}
class HttpClient{
public url:any |undefined;
constructor(){
}
getData(@logParams('xxxxx') uuid:any){
console.log(uuid);
}
}
var http:any = new HttpClient();
http.getData(123456);
console.log( http.apiUrl);
装饰器执行顺序
属性》方法》方法参数》类
如果有多个同样的装饰器,它会先执行后面的
function logClass1(params:string){
return function(target:any){
console.log('类装饰器1')
}
}
function logClass2(params:string){
return function(target:any){
console.log('类装饰器2')
}
}
function logAttribute1(params?:string){
return function(target:any,attrName:any){
console.log('属性装饰器1')
}
}
function logAttribute2(params?:string){
return function(target:any,attrName:any){
console.log('属性装饰器2')
}
}
function logMethod1(params?:string){
return function(target:any,attrName:any,desc:any){
console.log('方法装饰器1')
}
}
function logMethod2(params?:string){
return function(target:any,attrName:any,desc:any){
console.log('方法装饰器2')
}
}
function logParams1(params?:string){
return function(target:any,attrName:any,desc:any){
console.log('方法参数装饰器1')
}
}
function logParams2(params?:string){
return function(target:any,attrName:any,desc:any){
console.log('方法参数装饰器2')
}
}
@logClass1('http://www.itying.com/api')
@logClass2('xxxx')
class HttpClient{
@logAttribute1()
@logAttribute2()
public apiUrl:string | undefined;
constructor(){
}
@logMethod1()
@logMethod2()
getData(){
return true;
}
setData(@logParams1() attr1:any,@logParams2() attr2:any,){
}
}
var http:any=new HttpClient();
Typescript详解的更多相关文章
- 前端构建:Source Maps详解
一.前言 当使用CoffeeScript.ClojureScript编写前端脚本时,当使用Less.Sacc编写样式规则时,是否觉得调试时无法准确找到源码位置呢?当使用jquery.min.js等经压 ...
- 迈向angularjs2系列(2):angular2指令详解
一:angular2 helloworld! 为了简单快速的运行一个ng2的app,那么通过script引入预先编译好的angular2版本和页面的基本框架. index.html: <!DOC ...
- vue-cli脚手架中webpack配置基础文件详解
一.前言 原文:https://segmentfault.com/a/1190000014804826 vue-cli是构建vue单页应用的脚手架,输入一串指定的命令行从而自动生成vue.js+wep ...
- webpack入门详解
webpack入门详解(基于webpack 3.5.4 2017-8-22) webpack常用命令: webpack --display-error-details //执行打包 webpa ...
- Angular2 入门详解
AngularJS 2 快速入门 npm是什么? npm其实是Node.js Package Manager的简称,是Node.js包管理工具(package manager) 安装Node.js ...
- webpack.dev.conf.js详解
转载自:https://www.cnblogs.com/ye-hcj/p/7087205.html webpack.dev.conf.js详解 //引入当前目录下的utils.js文件模块var ut ...
- Angular2 内置指令 NgFor 和 NgIf 详解
http://www.jb51.net/article/89781.htm 在这一章节中,我们来学习如何使用Angular2来展示数据,以及如何使用它的内置指令NgFor和NgIf 首先要确保你有一个 ...
- Angular2配置文件详解
初学接触Angular2的时候,通过ng new your-project-name 命令生成一个工程空壳,本文来介绍下每个文件的作用及含义. 先来看看src的文件目录: 文件详解 File 文件 P ...
- Angular-cli新建项目目录结构详解
Angular-cli新建项目目录结构详解 在上一篇博客中我们已经通过Angular CLI命令行工具创建出来一个全新的Angular项目,要想写项目,首先我们要先搞清楚项目的目录结构是怎样的,每个文 ...
随机推荐
- Android茫茫半年求职路,终于斩获三个大厂offer
前言 2019年底,公司出现危机,开始"优化",本组一个小兄弟被"优化",于是我也着手开始做准备,将来若轮到我被"优化",出去面试时也好打个 ...
- 掌握JavaScript中的Promise,实现异步编程
事件循环 基本介绍 JavaScript是一门单线程的编程语言,所以没有真正意义上的并行特性. 为了协调事件处理.页面交互.脚本调用.UI渲染.网络请求等行为对主线程造成的影响,事件循环(event ...
- Install Fabric 1.8.3 Manually on Ubuntu 12.04
When you install Fabric with apt-get install fabric, you get a fabric with version 1.3.x, which is t ...
- Python--数据存储
新建测试文档测试.txt内容如下: 张三:今天天气真好. 李四:是的,真的太好了. 张三:阳光明媚. 李四:鸟语花香. 王五:装逼现场:请带好安全帽 张三:难得好天气,今天就不偷懒了. 李四:能把乞讨 ...
- MySQL-05-DDL/DCL/DML语句
DDL数据定义语言 库定义 1 创建数据库 mysql> create database school; mysql> create schema sch; mysql> show ...
- XSS之防御与绕过
很久之前的随笔讲过XSS的编码绕过的一些内容 本次侧重整理一下常见的防御思路,顺便补充一些针对性的绕过思路以及关于XSS个人想到的一些有趣的事情 开篇之前,先看一下XSS介绍(包括mXSS.uXSS. ...
- F与Q查询 事务 choices参数
F与Q查询 F查询 当我们需要将两个字段对应的数据进行比较时就需要用到F查询. select * from book where sold > stock 1.例如需要将售出部分数据和库存数据进 ...
- SQL 练习36
查询不同课程成绩相同的学生的学生编号.课程编号.学生成绩 select a.cid, a.sid, a.score from sc as a,sc as b WHERE a.sid = b.sid a ...
- C#硬件访问(摄像头、麦克风)
#需要引用:AForge类库.Microsoft.DirectX using System;using System.Windows.Forms;namespace CameraTest{ publi ...
- spring AOP事务
1 <bean id="tttt" class="com.ry.project.dataSouces.UserLogger"/> 2 <aop ...