index.js 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. import { use } from '../utils';
  2. const [sfc, bem] = use('uploader');
  3. export default sfc({
  4. inheritAttrs: false,
  5. props: {
  6. disabled: Boolean,
  7. beforeRead: Function,
  8. afterRead: Function,
  9. accept: {
  10. type: String,
  11. default: 'image/*'
  12. },
  13. resultType: {
  14. type: String,
  15. default: 'dataUrl'
  16. },
  17. maxSize: {
  18. type: Number,
  19. default: Number.MAX_VALUE
  20. }
  21. },
  22. computed: {
  23. detail() {
  24. return {
  25. name: this.$attrs.name || ''
  26. };
  27. }
  28. },
  29. methods: {
  30. onChange(event) {
  31. let { files } = event.target;
  32. if (this.disabled || !files.length) {
  33. return;
  34. }
  35. files = files.length === 1 ? files[0] : [].slice.call(files, 0);
  36. if (!files || (this.beforeRead && !this.beforeRead(files, this.detail))) {
  37. this.resetInput();
  38. return;
  39. }
  40. if (Array.isArray(files)) {
  41. Promise.all(files.map(this.readFile)).then(contents => {
  42. let oversize = false;
  43. const payload = files.map((file, index) => {
  44. if (file.size > this.maxSize) {
  45. oversize = true;
  46. }
  47. return {
  48. file: files[index],
  49. content: contents[index]
  50. };
  51. });
  52. this.onAfterRead(payload, oversize);
  53. });
  54. } else {
  55. this.readFile(files).then(content => {
  56. this.onAfterRead(
  57. { file: files, content },
  58. files.size > this.maxSize
  59. );
  60. });
  61. }
  62. },
  63. readFile(file) {
  64. return new Promise(resolve => {
  65. const reader = new FileReader();
  66. reader.onload = event => {
  67. resolve(event.target.result);
  68. };
  69. if (this.resultType === 'dataUrl') {
  70. reader.readAsDataURL(file);
  71. } else if (this.resultType === 'text') {
  72. reader.readAsText(file);
  73. }
  74. });
  75. },
  76. onAfterRead(files, oversize) {
  77. if (oversize) {
  78. this.$emit('oversize', files);
  79. } else {
  80. this.afterRead && this.afterRead(files, this.detail);
  81. }
  82. this.resetInput();
  83. },
  84. resetInput() {
  85. if (this.$refs.input) {
  86. this.$refs.input.value = '';
  87. }
  88. }
  89. },
  90. render(h) {
  91. const {
  92. accept,
  93. disabled
  94. } = this;
  95. return (
  96. <div class={bem()}>
  97. {this.slots()}
  98. <input
  99. { ...{ attrs: this.$attrs } }
  100. ref="input"
  101. type="file"
  102. accept={accept}
  103. class={bem('input')}
  104. disabled={disabled}
  105. onChange={this.onChange}
  106. />
  107. </div>
  108. );
  109. }
  110. });