国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > JavaScript > 正文

Vue的移動端多圖上傳插件vue-easy-uploader的示例代碼

2019-11-19 14:51:20
字體:
來源:轉載
供稿:網友

前言

這段時間趕項目,需要用到多文件上傳,用Vue進行前端項目開發。在網上找了不少插件,都不是十分滿意,有的使用起來繁瑣,有的不能適應本項目。就打算自己折騰一下,寫一個Vue的上傳插件,一勞永逸,以后可以直接使用。

目前vue-easy-uploader已上傳到GitHub和NPM,使用起來方便簡單,不需要繁瑣的配置即可投入生產,不過需要后端配合,實現上傳接口。

本項目GitHub地址: https://github.com/quanzaiyu/vue-easy-uploader

本項目NPM地址: https://www.npmjs.com/package/vue-easy-uploader

詳細的使用方法都在倉庫Readme中,就不贅述,這里談下本插件的設計開發思路。

插件介紹

vue-easy-uploader是一個多圖上傳插件。主要特性包括:

  1. 多文件上傳
  2. 上傳圖片預覽
  3. 上傳狀態監測
  4. 刪除指定圖片
  5. 清空圖片
  6. 重新上傳

后期版本迭代將不限于圖片,往通用文件上傳進行改進。

先看看上傳插件使用時候的效果圖:


目錄結構


index.js # 主入口文件store.js # 狀態管理uploader.vue # 上傳組件

文件解析

index.js

import uploader from './uploader'import store from './store'let plugin = {}plugin.install = function (_Vue, _store) { _Vue.component('uploader', uploader) _store.registerModule('imgstore', store)}export default plugin

這是插件的主入口文件,注冊了全局的上傳組件和狀態管理,使用時只需要在項目入口文件(一般是main.js)中加入以下代碼即可引入此插件:

import Vue from 'vue'import Vuex from 'vuex'import uploader from 'vue-easy-uploader' let store = new Vuex.Store({})Vue.use(uploader, store)

store.js

此文件為狀態管理配置文件,主要包含三個state:

img_upload_cache # 上傳文件緩存img_paths # 上傳狀態,包括 ready selected uploading finishedimg_status # 上傳后的路徑反饋數組(數據結構為Set集合)

針對每個state都有自己的mutation,用于改變state,規范上mutation都需要使用大寫字母加下劃線的形式,本人習慣使用小寫字母,不過都不是原則上的問題。

最重要的一個state是img_status,用于監視圖片上傳的狀態。包括以下幾個狀態:

ready # 上傳開始前的準備狀態 selected # 已選擇上傳文件 uploading # 開始上傳 finished # 上傳完畢 

在組件中可以通過改變上傳狀態實現文件的上傳,同時也可以監聽上傳狀態的變化而執行回調。如:

methods: { upload () {  this.$store.commit('set_img_status', 'uploading') }, submit () {  // some code }}computed: { ...mapState({  imgStatus: state => state.imgstore.img_status })},watch: { imgStatus () {  if (this.imgStatus === 'finished') {   this.submit()  } }}

上述代碼中,使用upload方法更新了上傳狀態,讓圖片開始執行上傳操作,使用watch進行上傳狀態的監視,當上傳完成(img_status狀態變為finished),執行回調函數submit。

源文件如下:

// Created by quanzaiyu on 2017/10/25 0025.var state = { img_upload_cache: [], img_paths: [], img_status: 'ready' // 上傳狀態 ready selected uploading finished}const actions = {}const getters = {}const mutations = { set_img_upload_cache (state, arg) {  state.img_upload_cache = arg }, set_img_paths (state, arg) {  state.img_paths = arg }, set_img_status (state, arg) {  state.img_status = arg }}export default { state, mutations, actions, getters}

uploader.vue

先看源代碼(為了節省空間,未貼出style部分的代碼):

<template> <div class="imgUploader">  <div class="file-list">   <section    v-for="(file, index) in imgStore" :key="index"    class="file-item draggable-item"   >    <img :src="file.src" alt="" ondragstart="return false;">    <span class="file-remove" @click="remove(index)">+</span>   </section>   <section class="file-item" v-if="imgStatus !== 'finished'">    <div class="add">     <span>+</span>     <input type="file" pictype='30010003' multiple      data-role="none" accept="image/*"      @change="selectImgs"      ref="file"     >    </div>   </section>  </div>  <div class="uploadBtn">   <section>    <span v-if="imgStore.length > 0" class="empty"     @click="empty">      {{imgStatus === 'finished' ? '重新上傳' : '清空'}}    </span>   </section>  </div> </div></template><script>import { mapState } from 'vuex'export default { props: ['url'], data () {  return {   files: [], // 文件緩存   index: 0 // 序列號  } }, computed: {  ...mapState({   imgStore: state => state.imgstore.img_upload_cache,   imgPaths: state => state.imgstore.img_paths,   imgStatus: state => state.imgstore.img_status  }) }, methods: {  // 選擇圖片  selectImgs () { # ①   let fileList = this.$refs.file.files   for (let i = 0; i < fileList.length; i++) {    // 文件過濾    if (fileList[i].name.match(/.jpg|.gif|.png|.bmp/i)) {      let item = {      key: this.index++,      name: fileList[i].name,      size: fileList[i].size,      file: fileList[i]     }     // 將圖片文件轉成BASE64格式     let reader = new FileReader() # ②     reader.onload = (e) => {      this.$set(item, 'src', e.target.result)     }     reader.readAsDataURL(fileList[i])     this.files.push(item)     this.$store.commit('set_img_upload_cache', this.files) // 存儲文件緩存     this.$store.commit('set_img_status', 'selected') // 更新文件上傳狀態    }   }  },  // 上傳圖片  submit () {   let formData = new FormData() # ③   this.imgStore.forEach((item, index) => {    item.name = 'imgFiles[' + index + ']' # ④    formData.append(item.name, item.file)   })   formData.forEach((v, k) => console.log(k, ' => ', v))   // 新建請求   const xhr = new XMLHttpRequest() # ⑤   xhr.open('POST', this.url, true)   xhr.send(formData)   xhr.onload = () => {    if (xhr.status === 200 || xhr.status === 304) {     let datas = JSON.parse(xhr.responseText)     console.log('response: ', datas)     // 存儲返回的地址     let imgUrlPaths = new Set()  # ⑥     datas.forEach(e => { // error === 0為成功狀態      e.error === 0 && imgUrlPaths.add(e.url)     })     this.$store.commit('set_img_paths', imgUrlPaths) // 存儲返回的地址     this.files = [] // 清空文件緩存     this.index = 0 // 初始化序列號     this.$store.commit('set_img_status', 'finished') // 更新文件上傳狀態    } else {     alert(`${xhr.status} 請求錯誤!`)    }   }  },  // 移除圖片  remove (index) {   this.files.splice(index, 1)   this.$store.commit('set_img_upload_cache', this.files) // 更新存儲文件緩存  },  // 清空圖片  empty () {   this.files.splice(0, this.files.length)   this.$store.commit('set_img_upload_cache', this.files) // 更新存儲文件緩存   this.$store.commit('set_img_paths', [])  } }, beforeCreate () {  this.$store.commit('set_img_status', 'ready') // 更新文件上傳狀態 }, destroyed () {  this.$store.commit('set_img_upload_cache', [])  this.$store.commit('set_img_paths', []) }, watch: {  imgStatus () {   if (this.imgStatus === 'uploading') {    this.submit()  # ⑦   }  },  imgStore () {   if (this.imgStore.length <= 0) {    this.$store.commit('set_img_status', 'ready') // 更新文件上傳狀態   }  } }}</script><style lang="less" scoped>...</style>

以上代碼中有一些注釋序號,是此插件設計的主要思路,其他代碼都比較容易理解,分別說下

① 選擇文件后執行,img_status狀態變為selected。
② 將帶上傳的圖片文件轉化為Base64格式,用于縮略圖顯示。
③ 創建一個表單對象,用于存儲待上傳的文件。
④ 注意這里的name屬性值,暫時寫死,后面設計打算從組件中指定name屬性,如果是多文件的話,name屬性的數組序號從0開始遞增。
⑤ 未依賴任何Ajax請求插件,使用原生的XMLHttpRequest對象創建請求。
⑥ 存儲上傳成功后服務器返回的上傳路徑。
⑦ 檢測上傳狀態,當在使用此插件時將img_status的狀態設置為uploading時執行上傳操作。

使用

參考本項目的GItHubNPM

注意

使用此插件時,需要與后端約定返回的數據格式,如下:

復制代碼 代碼如下:

[{"error":0,"url":"http://uploads//api//201711//25//fde412bd83d3ec5d6a49769bd0c143cd.jpg"},{"error":0,"url":"http://uploads//api//201711//25//c6fd51f0388c63a0b6d350331c945fb1.jpg"}]

預覽如下:


返回的是一個上傳后的路徑數組,包括error和url字段,每個文件有自己的上傳狀態,當error為0的時候為上傳成功,并返回上傳后的路徑url

改進

后續版本打算進行如下改進

  1. 把表單的name屬性名稱通過組件傳遞。
  2. 自定義上傳成功后服務器響應的數據格式,比如自定義error的名稱和其值所表示的狀態。
  3. 支持其他類型文件的上傳,可以在組件中自行制定上傳的文件類型,及其預覽方式。

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持武林網。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 如东县| 乐都县| 青神县| 宝丰县| 沛县| 长宁县| 富锦市| 西贡区| 天长市| 云林县| 漳浦县| 遂川县| 阿坝县| 天峻县| 蒙阴县| 阿鲁科尔沁旗| 龙陵县| 韶关市| 平遥县| 黄梅县| 兴城市| 康马县| 济宁市| 莱西市| 德昌县| 龙里县| 托里县| 青岛市| 昌图县| 嘉善县| 满洲里市| 德化县| 襄汾县| 轮台县| 南江县| 兴安盟| 灵石县| 南涧| 花莲县| 普格县| 安丘市|