diff --git a/docs/demos/views/uploader.vue b/docs/demos/views/uploader.vue index 9ab039be2..f632001f7 100644 --- a/docs/demos/views/uploader.vue +++ b/docs/demos/views/uploader.vue @@ -10,7 +10,7 @@
- +
diff --git a/docs/markdown/en-US/uploader.md b/docs/markdown/en-US/uploader.md index 4b6ed496d..5b8cb8f75 100644 --- a/docs/markdown/en-US/uploader.md +++ b/docs/markdown/en-US/uploader.md @@ -30,10 +30,10 @@ export default { ``` #### Set input attr -You can set native properties such as `accpet` on Uploader, and the input will automatically inherits the attribute. +You can set native properties such as `accpet`、`multiple` on Uploader, and the input will automatically inherits the attribute. ```html - + ``` diff --git a/docs/markdown/zh-CN/uploader.md b/docs/markdown/zh-CN/uploader.md index 19bba563b..95ea7532d 100644 --- a/docs/markdown/zh-CN/uploader.md +++ b/docs/markdown/zh-CN/uploader.md @@ -28,10 +28,10 @@ export default { ``` #### 设置 Input 属性 -可以直接在 Uploader 上设置 accpet 等原生属性,input 会自动继承该属性 +可以直接在 Uploader 上设置 accpet、multiple 等原生属性,input 会自动继承该属性 ```html - + ``` diff --git a/packages/uploader/index.vue b/packages/uploader/index.vue index 7f623204c..bf46e2910 100644 --- a/packages/uploader/index.vue +++ b/packages/uploader/index.vue @@ -7,7 +7,7 @@ class="van-uploader__input" v-bind="$attrs" :disabled="disabled" - @change="onValueChange" + @change="onChange" /> @@ -29,30 +29,52 @@ export default create({ }, methods: { - onValueChange(event) { - if (this.disabled) { + onChange(event) { + let { files } = event.target; + if (this.disabled || !files.length) { return; } - const file = event.target.files[0]; - if (!file || (this.beforeRead && !this.beforeRead(file))) { + files = files.length === 1 ? files[0] : [].slice.call(files, 0); + if (!files || (this.beforeRead && !this.beforeRead(files))) { return; } - const reader = new FileReader(); - reader.onload = (e) => { - this.afterRead && this.afterRead({ - file, - content: e.target.result + if (Array.isArray(files)) { + Promise.all(files.map(this.readFile)).then(contents => { + this.onAfterRead( + files.map((file, index) => ({ + file: files[index], + content: contents[index] + })) + ); + }); + } else { + this.readFile(files).then(content => { + this.onAfterRead({ file: files, content }); }); - this.$refs.input && (this.$refs.input.value = ''); - }; - - if (this.resultType === 'dataUrl') { - reader.readAsDataURL(file); - } else if (this.resultType === 'text') { - reader.readAsText(file); } + }, + + readFile(file) { + return new Promise(resolve => { + const reader = new FileReader(); + + reader.onload = event => { + resolve(event.target.result); + }; + + if (this.resultType === 'dataUrl') { + reader.readAsDataURL(file); + } else if (this.resultType === 'text') { + reader.readAsText(file); + } + }); + }, + + onAfterRead(file) { + this.afterRead && this.afterRead(file); + this.$refs.input && (this.$refs.input.value = ''); } } }); diff --git a/test/unit/specs/uploader.spec.js b/test/unit/specs/uploader.spec.js index 78745979b..ea1be0a7f 100644 --- a/test/unit/specs/uploader.spec.js +++ b/test/unit/specs/uploader.spec.js @@ -1,8 +1,10 @@ import Uploader from 'packages/uploader'; import { mount } from 'avoriaz'; + window.File = function() { this.name = 'test'; }; + window.FileReader = function() { this.readAsDataURL = this.readAsText = function() { this.onload && this.onload({ @@ -12,97 +14,91 @@ window.FileReader = function() { }); }; }; + +const mockFile = new File([], '/Users'); + describe('Uploader', () => { let wrapper; afterEach(() => { wrapper && wrapper.destroy(); }); - it('enabled', () => { - wrapper = mount(Uploader, { - propsData: { - disabled: false - } - }); - - expect(wrapper.contains('input')).to.equal(true); - expect(wrapper.vm.onValueChange({ target: { files: [] }})).to.equal(undefined); - }); - it('disabled', () => { + const afterRead = sinon.spy(); wrapper = mount(Uploader, { propsData: { - disabled: true + disabled: true, + afterRead } }); expect(wrapper.contains('input')).to.equal(true); - expect(wrapper.vm.onValueChange({ target: { files: [] }})).to.equal(undefined); + wrapper.vm.onChange({ target: { files: [] }}); + expect(afterRead.calledOnce).to.be.false; }); it('before read', () => { + const afterRead = sinon.spy(); wrapper = mount(Uploader, { propsData: { - disabled: false, - beforeRead: () => { - return false; - } + beforeRead: () => false, + afterRead } }); - expect(wrapper.contains('input')).to.equal(true); - expect(wrapper.vm.onValueChange({ target: { files: [new File([], '')] }})).to.equal(undefined); + wrapper.vm.onChange({ target: { files: [mockFile] }}); + expect(afterRead.calledOnce).to.be.false; }); - it('read text', () => { + it('read text', done => { wrapper = mount(Uploader, { propsData: { - disabled: false, resultType: 'text', afterRead: (file) => { + expect(file.content).to.equal('test'); + done(); } } }); - expect(wrapper.contains('input')).to.equal(true); - expect(wrapper.vm.onValueChange({ target: { files: [new File([], '/Users')] }})).to.equal(undefined); + wrapper.vm.onChange({ target: { files: [mockFile] }}); }); - it('read text no after hook', () => { + it('read dataUrl', done => { wrapper = mount(Uploader, { propsData: { - disabled: false, - resultType: 'text' - } - }); - - expect(wrapper.contains('input')).to.equal(true); - expect(wrapper.vm.onValueChange({ target: { files: [new File([], '/Users')] }})).to.equal(undefined); - }); - - it('read dataUrl', () => { - wrapper = mount(Uploader, { - propsData: { - disabled: false, - resultType: 'dataUrl', afterRead: (file) => { + expect(file.content).to.equal('test'); + done(); } } }); - expect(wrapper.contains('input')).to.equal(true); - expect(wrapper.vm.onValueChange({ target: { files: [new File([], '/Users')] }})).to.equal(undefined); + wrapper.vm.onChange({ target: { files: [mockFile] }}); }); it('unknown resultType', () => { + const afterRead = sinon.spy(); wrapper = mount(Uploader, { propsData: { - disabled: false, - resultType: 'xxxx' + resultType: 'xxxx', + afterRead + } + }); + wrapper.vm.onChange({ target: { files: [mockFile] }}); + expect(afterRead.calledOnce).to.be.false; + }); + + it('read multiple files', done => { + wrapper = mount(Uploader, { + propsData: { + afterRead: (file) => { + expect(file.length).to.equal(2); + done(); + } } }); - expect(wrapper.contains('input')).to.equal(true); - expect(wrapper.vm.onValueChange({ target: { files: [new File([], '/Users')] }})).to.equal(undefined); + wrapper.vm.onChange({ target: { files: [mockFile, mockFile] }}); }); });