之前写了一个angular1x的实现,但手痒痒于是就搞了一下angular4的实现方式,不BB直接上代码了。样式里用到了fontawesome的图标

首先我们直接看如何调用
别忘了我们还要在父元素的component.ts上创建previewImgFile这个变量,否则就会报错,这里之所以和父组件通信,就是要把我们上传的file对象传给服务器,所以需要监听子组件的上传图片

<app-previewimg  [(previewImgFile)]="previewImgFile"></app-previewimg>

我们再来看下这个组件的component和service
component.ts

import {Component, EventEmitter, Input, OnInit, Output} from '@angular/core';
import {PreviewimgService} from "./previewimg.service";

@Component({
  selector: 'app-previewimg',
  templateUrl: './previewimg.component.html',
  styleUrls: ['./previewimg.component.css']
})
export class PreviewimgComponent implements OnInit {

  @Input()
  previewImgFile
  @Output()
  previewImgFileChange: EventEmitter<string> = new EventEmitter();

  previewImgSrcs = [];

  constructor(public previewimgService: PreviewimgService) { }

  ngOnInit() {
  }
  previewPic(event) {
    if(!event.target.files[0]) {
      return;
    }
    let that = this;
    this.previewimgService.readAsDataUrl(event.target.files[0]).then(function(result) {
      that.previewImgSrcs.push(result)
      let file = event.target.files[0];
      that.previewImgFile.push(file)
      that.previewImgFileChange.emit(that.previewImgFile);
    })

  }
  remove(i) {
    this.previewImgSrcs.splice(i,1);
    this.previewImgFile.splice(i,1);
  }
}

import { Injectable } from '@angular/core';

@Injectable()
export class PreviewimgService {

  constructor() { }
  getReader(resolve, reject) {
    let reader = new FileReader();
    reader.onload = this.Onload(reader, resolve);
    reader.onerror = this.OnError(reader, reject);
    return reader;
  }
  readAsDataUrl(file){
    let that = this;
    return new Promise(function(resolve,reject){
      let reader = that.getReader(resolve, reject);
      reader.readAsDataURL(file);
    })
  }

  Onload(reader: FileReader, resolve) {
    return () => {
      resolve(reader.result);
    }
  }

  OnError(reader: FileReader, reject) {
    return () => {
      reject(reader.result);
    }
  }

}

component.css

.preview-label {
  width: 100px;
  height:100px;
  border:1px dotted #ccc;
  position: relative;
  vertical-align: top;
  display: inline-block
}
.preview-label>input {
  display: none;
}
.preview-label .uploadimgicon {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%,-50%);
}
.preview-label .uploadimgremove {
  position: absolute;
  top:5px;
  right:5px;
}

component.html

<label class="preview-label" *ngFor="let img of previewImgSrcs let i = index">
  <img src="{{img}}" width="100px" height="100px">
  <i class="fa fa-remove uploadimgremove" (click)="remove(i)"></i>
</label>
<label class="preview-label"><input type="file" (change)="previewPic($event)"><i class="fa fa-2x fa-plus uploadimgicon"></i></label>

好啦,如果有bug可以及时反馈下,如果以后需要什么属性在继续封装,如果大家还有别的简单的封装,希望一起讨论下,博主小白,有错还希望见谅啊~~~