Angular UI组件编写学习记录 - Button
写在前面的话
准备工作QuickStart这个项目种子包含了Angular、Typescript,转译工具是tsc,构建工具是Systemjs。 项目以官方文档里面推荐的QuickStart开始,先从GitHub上Clone下来: git clone https://github.com/angular/quickstart.git quickstart cd quickstart npm install npm start 项目已经可以正常运行了,但是因为Clone下来的版本有许多不需要的东西,我们先按照文档里的操作删除原有的git版本库: rm -rf .git # OS/X (bash) rd .git /S/Q # windows 然后删除项目里的不必要文件(non-essential files )
OS/X (bash) xargs rm -rf < non-essential-files.osx.txt rm src/app/*.spec*.ts rm non-essential-files.osx.txt Windows for /f %i in (non-essential-files.txt) do del %i /F /S /Q rd .git /s /q rd e2e /s /q 这里可以把项目备份一份,以便后面的项目继续使用。 接着修改项目名字和相应的package信息,我们改成button相关的。 git init 由于是写模块,所以我们在项目根目录下新建一个example的文件夹,将src下的文件统统移到example上,同时需要修改package上的脚本信息,将所有指向src文件的命令统统指向example,然后运行命令: npm start 文件正常编译并启动。 第一个模块 ButtonAngular中UI组件一般以特性模块的方式出现, 我们在src文件下新建几个文件: - index.ts //用于编写Button Module - button.ts //用于编写Button Component - button.spec.ts //用于编写Button 测试用例(karam + jasmine),之后完善 - button.html //用于编写模板 - style/button.css //用于编写样式 编写Modulesrc/index.tsimport { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; import { AsButton } from './button' @NgModule({ imports: [ CommonModule ],exports: [ AsButton],declarations: [ AsButton ] }) export class AsButtonModule {} 这里将模块命名为AsButtonModule,从button文件引入AsButton组件并在Module文件声明和导出。 编写Component文件src/button.tsimport { Component,Input,Output,EventEmitter,SimpleChange,ViewChild,ElementRef } from '@angular/core' import * as classNames from 'classnames' export type ButtonType = 'primary' | 'ghost' | 'dashed' | 'danger'; export type ButtonShape = 'circle' | 'circle-outline'; export type ButtonSize = 'small' | 'large'; @Component({ moduleId: module.id,selector: 'as-button',templateUrl: 'button.html',styleUrls: ['style/button.css'] }) export class AsButton { private classes: any; private _loading: boolean; private clicked: boolean; private oldClicked: boolean; timeout: any; delayTimeout: any; // 接口声明 @Input() type: string @Input() htmlType: string @Input() icon: string @Input() shape: ButtonShape @Input() prefixCls: string @Input() size: ButtonSize @Input() loading: boolean @Input() ghost: boolean @Output() onClick = new EventEmitter<Event>(); @Output() onMouseUp = new EventEmitter<Event>(); @ViewChild('AsButton') button: ElementRef; constructor(){ this.prefixCls = "as-btn"; this.clicked = false; this.ghost = false; this._loading = false; } // 初始化class样式 ngOnInit(){ this.updateClass() } // loading状态更新 ngOnChange(changes: {[propKey: string]: SimpleChange}){ const currentLoading = this.loading const loading = changes["loading"]; if (currentLoading) { clearTimeout(this.delayTimeout); } if (loading){ this.delayTimeout = setTimeout(() => { this._loading = !!loading }) } else { this._loading = !!loading } } ngDoCheck() { // 检测如果this.clicked的状态改变,则触发class更新 if (this.clicked !== this.oldClicked) { this.updateClass() this.oldClicked = this.clicked } } /** * 绑定点击事件 */ handleClick = (e: Event) => { this.clicked = true; clearTimeout(this.timeout); // 防止点击过快,延迟500毫秒 this.timeout = setTimeout(() => this.clicked = false,500); // 如果父级组件绑定了点击事件,则执行 const onClick = this.onClick; if (onClick) { onClick.emit(e) } } handleMouseUp = (e: Event) => { this.button.nativeElement.blur(); if (this.onMouseUp) { this.onMouseUp.emit(e) } } // 更新Class的方法 updateClass = () =>{ const { type,htmlType,icon,shape,prefixCls,size,ghost } = this const sizeCls = ({ large: 'lg',small: 'sm',})[size] || ''; this.classes = classNames(prefixCls,{ [`${prefixCls}-${type}`]: !!type,[`${prefixCls}-${shape}`]: !!shape,[`${prefixCls}-${sizeCls}`]: !!sizeCls,// [`${prefixCls}-icon-only`]: !children && icon,[`${prefixCls}-loading`]: !!this._loading,[`${prefixCls}-clicked`]: !!this.clicked,[`${prefixCls}-background-ghost`]: !!ghost,}) } } 因为是移植的关系,组件的API和代码实现基本参考原版的Ant.Design。 编写HTML模板src/button.html<button #AsButton [class]="classes" [type]="htmlType || 'button'" (click)="handleClick($event)" (mouseup)="handleMouseUp()"> <span> <ng-content></ng-content> </span> </button> 编写CSS样式文件src/style/button.less to .css参考Ant.Design的Button样式 导入到Example我们需要看看组件效果是否达到了预期。 修改App Moduleexample/app/app.module.tsimport { NgModule } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import { AppComponent } from './app.component'; import { AsButtonModule } from '../../src/index'; @NgModule({ imports: [ BrowserModule,AsButtonModule ],declarations: [ AppComponent ],bootstrap: [ AppComponent ] }) export class AppModule { } 修改App Componentexample/app/app.component.tsimport { Component } from '@angular/core'; @Component({ selector: 'my-app',templateUrl: './app.component.html',}) export class AppComponent { loading = false; handleOK(){ console.log("click") }; } 修改App Component Html这里的html文件原版是没有的,我们来新建一个: App.component.html<div> <as-button type="primary" >Primary</as-button> <as-button>Default</as-button> <as-button type="dashed">Dashed</as-button> <as-button type="danger" (onClick)="handleOK($event)">Danger</as-button> </div> 如果此时运行了npm start,命令行应该提示无法找到src下面的文件,报404。 { "server": { "baseDir": "examples","routes": { "/node_modules": "node_modules",+ "/src": "src" } } } 这样,Systemjs就能正确的将src下面编译好的js文件导入到浏览器中了。 预期中的效果
本文涉及代码:https://github.com/ng-compone... (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |