上图:

module:

import {NgModule} from "@angular/core";
import {CommonModule} from "@angular/common"
import {PpInputComponent} from './pp-input'
import {FormsModule} from "@angular/forms"; @NgModule({
declarations: [PpInputComponent],
imports: [
CommonModule,
FormsModule,
],
exports: [PpInputComponent],
}) export class PpInputComponentModule {
}

 ts:

import {Component, Input, Output, EventEmitter, OnInit, ViewChild, ElementRef, Renderer2, AfterViewInit} from '@angular/core';

/**
* Generated class for the PpInputComponent component.
*
* See https://angular.io/api/core/Component for more info on Angular
* Components.
*/
@Component({
selector: 'pp-input',
templateUrl: 'pp-input.html'
})
export class PpInputComponent implements OnInit, AfterViewInit {
constructor(private renderer: Renderer2) {
} @ViewChild('ppLabel') private ppLabel: ElementRef; // 获取元素
@Input() ppValue: any; // input的值,双向绑定
@Input('pp-label') label: string = 'Label'; // label文案
@Input() validate: any = function (input) { // 验证数据方法
if (input) {
return true
} else {
return false
}
};
@Input() type: string = 'text'; // input类型
@Input() x: string; // label的X轴偏移量
@Input() isRequired: boolean; // false
@Input('error-message') errorMessage: string = 'validate error'; // 错误提示信息 @Output() ppValueChange = new EventEmitter(); actived: boolean = false; // 样式控制
float: boolean; // label是否浮动
showErrMsg: boolean = false; // 是否显示错误信息 ngOnInit() {
if (this.ppValue) {
this.float = true;
this.actived = true;
} else {
this.float = false;
}
} ngAfterViewInit() {
if (this.x) {
this.renderer.setStyle(this.ppLabel.nativeElement, 'transform', `translate3d(${Number(this.x) / 100}rem, 0.48rem, 0)`)
}
} // 获得焦点
ppFocus() {
this.float = true;
} // 失去焦点
ppBlur() {
if (this.ppValue) {
this.float = true;
} else {
this.float = false;
}
if (this.validate(this.ppValue)) {
this.showErrMsg = false;
} else {
this.showErrMsg = true;
}
} // 更新父组件model值
changeValue() {
this.ppValueChange.emit(this.ppValue);
if (this.validate(this.ppValue)) {
this.actived = true;
this.showErrMsg = false;
} else {
this.actived = false;
}
}
}

  scss

pp-input {
.pp-input-container {
border-bottom: 1px solid #C1CCD5;
height: 0.92rem;
&.actived {
border-color: #6308C7
}
.label {
font-size: 0.28rem;
color: #95A1AB;
position: relative;
font-family: Avenir-Medium;
pointer-events: none;
transform: translate3d(0,0.48rem, 0);
transition: all 0.2s;
margin: 0.11rem 0.08rem 0.11rem 0;
&.actived {
transform: translate3d(0, 0, 0)!important;
font-size: 0.22rem;
transition: all 0.2s;
.actived {
color: #6308C7
}
}
.required {
color: #F44E4E
}
}
.pp-input {
border: none;
font-size: 0.28rem;
height: 0.5rem;
line-height: 0.5rem;
}
.content {
display: flex;
align-items: center;
}
}
.error-message {
color: #F44E4E;
font-size: 0.22rem;
height: 0;
line-height: 0.4rem;
opacity: 0.5;
transition: all 0.2s;
overflow: hidden;
&.show {
opacity: 1;
height: 0.4rem;
transition: all 0.2s;
}
}
}

  html

<!-- Generated template for the PpInputComponent component -->
<div class="pp-input-wrapper">
<div class="pp-input-container" [class.actived]="actived">
<div class="label" [class.actived]="float" #ppLabel>
<span class="required" *ngIf="isRequired">*</span><span [class.actived]="actived">{{label}}</span>
</div>
<div class="content">
<ng-content></ng-content>
<input class="pp-input"
(focus)="ppFocus()"
(blur)="ppBlur()"
(keyup)="changeValue()"
[type]="type"
[(ngModel)]="ppValue">
</div>
</div>
<div class="error-message" [class.show]="showErrMsg">{{errorMessage}}</div>
</div>

 目前实现可传入label文案, label的x轴偏移,input类型,验证数据的validate方法,input的双向绑定value值,错误提示信息等

用<ng-content></ng-content>预留的编辑位置,可以添加更多的html,方便扩展,例如上图的国家图标显示。

可以考虑把所有的@Input集合成一个config,html的font-size的值我是动态算的,所以样式rem的值可能要修改成你需要的大小。

ps: 之前用vue组件也写过类型的组件,传送门:https://www.cnblogs.com/cong-bao/p/9204940.html

[ionic3.x开发记录]参考ionic的float-label动效,写一个项目内通用的input组件,易扩展的更多相关文章

  1. YII框架开发一个项目的通用目录结构

    YII框架开发一个项目的通用目录结构: 3 testdrive/ 4 index.php Web 应用入口脚本文件 5 assets/ 包含公开的资源文件 6 css/ 包含 CSS 文件 7 ima ...

  2. [ionic3.x开发记录]ng-content使用

    在ionic开发公用组件的时候,我一直在想有没有angular有没有像vue一样的slot插槽.方便组件后期扩展. 然后去翻文档,发现有ng-content这么个东西,用法很像vue的slot. 组件 ...

  3. [ionic3.x开发记录]ios下页面过渡效果不出现的小坑

    如果内容没有被<ion-content></ion-content>或者<ion-header></ion-header>标签包裹,页面过渡的时候是没有 ...

  4. 参考MySQL Internals手册,使用Golang写一个简单解析binlog的程序

    GreatSQL社区原创内容未经授权不得随意使用,转载请联系小编并注明来源. MySQL作为最流行的开源关系型数据库,有大量的拥趸.其生态已经相当完善,各项特性在圈内都有大量研究.每次新特性发布,都会 ...

  5. 参考JDK1.8源码,自己写一个类似于ArrayList的动态数组

    1. ArrayList的基本实现原理 ArrayLiST其内部用一个普通数组来存储数据,当此数组不够容纳新添加的元素的时候,则创建一个更大长度的新数组,并将原来数组中的元素复制到新数组中. 2.Ar ...

  6. YII框架开发一个项目的通用目录结构:

    testdrive/    index.    assets/    css/    images/    themes/           yiic.       commands/        ...

  7. Anytime项目开发记录0

    Anytime,中文名:我很忙. 开发者:孤独的猫咪神. 这个项目会持续更新,直到我决定不再维护这个APP. 2014年3月10日:近日有事,暂时断更.希望可以会尽快完事. 2014年3月27日:很抱 ...

  8. 如何用Eggjs从零开始开发一个项目(1)

    前言 "纸上得来终觉浅,绝知此事要躬行."虽然node一直在断断续续地学,但总是东一榔头西一榔头的,没有一点系统,所以打算写一个项目来串联一下之前的学习成果. 为什么选择Eggjs ...

  9. ionic js 滑动框ion-slide-box 滑动框是一个包含多页容器的组件,每页滑动或拖动切换

    ionic 滑动框 ion-slide-box 滑动框是一个包含多页容器的组件,每页滑动或拖动切换: 效果图如下: 用法 <ion-slide-box on-slide-changed=&quo ...

随机推荐

  1. vue的配置环境篇

    1.电脑已经安装的nodejs和webpack. 2.1)打开cmd.win+r.可以直接输入node -v查看版本.安装淘宝镜像  npm install -g cnpm --registry=ht ...

  2. Flask开发微电影网站(四)

    会员中心页面,如下图所示 用户登录后,修改密码页面,如下图所示 用户查看自己的评论页面,如下图所示 用户查看自己的登录日志页面,如下图所示 用户查看自己收藏的电影的页面,如下图所示 1. 定义用户主页 ...

  3. C++\CLI语法 在项目中的使用

    通常情况下,对一个标准的com组件进行集成,网上普遍使用的方式有: 1.#import *.dll 或 #import *.ocx的方式,VS编译器重新编译后,就会自动生成组件对应的*.tlh文件,该 ...

  4. Gradle sync failed: SSL peer shut down incorrectly

    http://www.th7.cn/Program/Android/201604/817127.shtml 问题是在更新版本后出现的,被墙隔断的原因 引自大神解决方案 这个问题通常出现在Android ...

  5. JavaScript我学之七数组

    本文是金旭亮老师网易云课堂的课程笔记,记录下来,以供备忘. 数组是“多态数组" ,啥都可以放 //JavaScript中的多态数组 var arr = ["one", 2 ...

  6. python全栈开发day111-flask路由及其参数,Flask配置,蓝图,几个装饰器、闪现、send_file、jsonify

    1.endpoint参数,解决视图函数重名问题(包括装饰后重名问题) http://www.cnblogs.com/eric-nirnava/p/endpoint.html 每个应用程序app都有一个 ...

  7. 2018-2019-1 20189201《Linux内核原理与分析》第三周作业

    写作业之前,写了时光博物馆参观感受.1978-2018 40年的改革开放历程. 一.C语言中内嵌汇编语言的写法 内嵌汇编的语法如下: asm volatile ( 汇编语句模版: 输出部分: 输入部分 ...

  8. python 单行写法

    if not any([_ in fingers for _ in finger_ids])

  9. fixed定位文本框引发的问题

    <!-- 代码段1 --> <body> <!-- 可以滚动的区域 --> <main id="J_box"> <!-- 内容 ...

  10. 微信小程序做radio,可以拖动进度条

    很简单的一个音乐播放器 data:{ src: 'http://ws.stream.qqmusic.qq.com/M500001VfvsJ21xFqb.mp3?guid=ffffffff82def4a ...