上图:

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. Qt websocket

    1.pro  添加 QT += websockets #ifndef MYWEBSOCKETSERVER_H #define MYWEBSOCKETSERVER_H #include <QObj ...

  2. Python基础【第二篇】

    一.Python的标准数据类型 Python 3中主要有以下6中数据类型: Number(数字).String(字符串).List(列表).Tuple(元组).Sets(集合).Dictionary( ...

  3. udp/tcp流程

    udp: 1.创建套接字 socket 2.绑定本地ip/port bind 3.收发数据 sendto/recvfrom 4.关闭套接字 close tcp客户端: 1.创建套接字 socket 2 ...

  4. 27)django-form操作示例(动态Select数据,自定义字段验证,全局验证等)

    1)普通传递select数据 # -*- coding:utf-8 -*- __author__ = 'shisanjun' from django import forms from django. ...

  5. for/while循环运用(do while)

    //for循环用于知道次数的循环,while用于不知道的次数的循环//第1种写法 while循环 import java.util.Scanner;//插入util工具包 public class H ...

  6. Oracle中和mysql中函数的区别

    oracle                  -->                 mysqlto_char(sysdate,'yyyy-mm-dd')-->date_format(s ...

  7. Postgresql查询出换行符和回车符:

    1.有时候,业务因为回车和换行出现的错误,第一步,首先要查询出回车符和换行符那一条数据: -- 使用chr()和chr()进行查询 SELECT * )||)||'%'; -- 其实查询chr()和c ...

  8. 03.DataStructure

    01.list ''' list 특징 - 1차원 배열 구조 형식) 변수 = [값1, 값2] - 다양한 자료형 저장 가능 - index 사용=순서 존재 형식) 변수[n] - 값 수정( ...

  9. IdentityServer4 密码模式认证

     授权服务器设置 添加用户 添加测试用户,也可以从数据库查 public static List<TestUser> GetTestUser() { return new List< ...

  10. PyCharm 怎么查看 Python 的变量类型和变量内容

    一.在程序的某一行添加断点 二.选择 debug 程序