溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

怎么用Vue組件封裝上傳圖片和視頻

發(fā)布時(shí)間:2021-07-30 18:17:38 來(lái)源:億速云 閱讀:189 作者:chen 欄目:開發(fā)技術(shù)

這篇文章主要介紹“怎么用Vue組件封裝上傳圖片和視頻”,在日常操作中,相信很多人在怎么用Vue組件封裝上傳圖片和視頻問題上存在疑惑,小編查閱了各式資料,整理出簡(jiǎn)單好用的操作方法,希望對(duì)大家解答”怎么用Vue組件封裝上傳圖片和視頻”的疑惑有所幫助!接下來(lái),請(qǐng)跟著小編一起來(lái)學(xué)習(xí)吧!

怎么用Vue組件封裝上傳圖片和視頻 

首先下載依賴:

cnpm i -S vue-uuid ali-oss

圖片和視頻字段都是數(shù)組類型,保證可以上傳多個(gè)文件。

UploadImageVideo:

<!--UploadImageVideo 分片上傳    -->
<template>
  <div class="UploadImageVideo">
    <el-upload
      action
      :on-change="handleChange"
      :on-remove="handleRemove"
      :limit="limitFileNumber"
      :on-exceed="handleExceed"
      :file-list="_fileList"
      :http-request="handleHttpRequest"
      :before-upload="handleBeforeUpload"
      :multiple="isMultiple"
    >
      <el-button slot="trigger" size="small" type="primary">選擇文件</el-button>
      <div slot="tip" class="el-upload__tip">{{ tip }}</div>
    </el-upload>
 
    <el-dialog
      title="上傳進(jìn)度"
      :visible.sync="dialogTableVisible"
      :close-on-click-modal="false"
      :modal-append-to-body="false"
    >
      <el-progress :text-inside="true" :stroke-width="26" :percentage="percentage"></el-progress>
    </el-dialog>
  </div>
</template>
 
<script>
import { uuid } from "vue-uuid";
const OSS = require("ali-oss");
 
export default {
  name: "",
  components: {},
  props: {
    region: {
      type: String,
      default: "oss-cn-chengdu"
    },
    accessKeyId: {
      type: String,
      default: "xxx"
    },
    accessKeySecret: {
      type: String,
      default: "xxx"
    },
    //存儲(chǔ)位置
    bucket: {
      type: String,
      required: true
    },
    currentUrls: {
      type: Array,
      default: () => [],
      required: true
    },
    //限制上傳文件數(shù)量
    limitFileNumber: {
      type: Number,
      default: 1
    },
    //是否支持多選
    isMultiple: {
      type: Boolean,
      default: false
    },
    //文件格式
    fileType: {
      type: String,
      default: ""
    },
    //提示
    tip: {
      type: String
    }
  },
  data() {
    return {
      client: new OSS({
        region: this.region,
        accessKeyId: this.accessKeyId,
        accessKeySecret: this.accessKeySecret,
        bucket: this.bucket
      }),
      percentage: 0,
      dialogTableVisible: false,
      fileList: []
    };
  },
  computed: {
    //注意:計(jì)算屬性里面慎用console.log()來(lái)打印,因?yàn)橛锌赡艽蛴〉淖兞渴且蕾嚹硞€(gè)屬性而出現(xiàn)該計(jì)算屬性重復(fù)調(diào)用?。。。。?!
    _fileList() {
      const arr = [];
      //一定要this.currentUrls判斷一下是否非空,否則要報(bào)錯(cuò)
      if (this.currentUrls.length !== 0) {
        for (const item of this.currentUrls) {
          let { pathname } = new URL(item);
          arr.push({ name: decodeURIComponent(pathname), url: item });
        }
      }
 
      this.fileList = arr; //這行代碼很重要??!
      return arr;
    }
  },
  created() {},
  mounted() {},
  methods: {
    handleChange(file, fileList) {
      this.fileList = fileList;
    },
    handleRemove(file, fileList) {
      this.fileList = fileList;
    },
    handleExceed(files, fileList) {
      this.$message.warning(
        `當(dāng)前限制選擇 ${this.limitFileNumber} 個(gè)文件,本次選擇了 ${
          files.length
        } 個(gè)文件,共選擇了 ${files.length + fileList.length} 個(gè)文件`
      );
    },
 
    //注意:為了讓自定義上傳handleHttpRequest生效,需滿足:
    // 1、設(shè)置:auto-upload='true'或者不寫這個(gè)屬性,因?yàn)樗J(rèn)為true  2、設(shè)置action='#'或者直接寫action
    handleHttpRequest(file) {
      //雖然沒有內(nèi)容,但是這個(gè)函數(shù)不能少!
    },
    //注意:自定義上傳handleHttpRequest必須要生效,才會(huì)觸發(fā)before-upload鉤子函數(shù)
    handleBeforeUpload(file) {
      if (this.fileType == "image") {
        let { type, size, name } = file;
        let isJPEG = type === "image/jpeg";
        let isJPG = type === "image/jpg";
        let isPNG = type === "image/png";
        let isLt5M = size / 1024 / 1024 < 5;
        if (!isJPEG && !isJPG && !isPNG) {
          this.$message.error("上傳圖片只能是 JPEG/JPG/PNG  格式!");
          return false;
        }
        if (!isLt5M) {
          this.$message.error("單張圖片大小不能超過(guò) 5MB!");
          return false;
        }
      }
      if (this.fileType == "video") {
        let { type, size, name } = file;
        let isMP4 = type === "video/mp4";
        let isLt50M = size / 1024 / 1024 < 50;
        if (!isMP4) {
          this.$message.error("上傳視頻只能是 MP4  格式!");
          return false;
        }
        if (!isLt50M) {
          this.$message.error("單個(gè)視頻大小不能超過(guò) 50MB!");
          return false;
        }
      }
    },
    // 分片上傳數(shù)據(jù),可展示進(jìn)度條。上傳重命名后的文件到alioss, 并返回單個(gè)文件url字符串。可支持中文文件名
    async UploadImageVideo(filename, file) {
      let newFileName =
        filename.split(".")[0] + "-" + uuid.v1() + "." + filename.split(".")[1];
      let that = this;
      that.dialogTableVisible = true;
 
      let {
        res: { requestUrls }
      } = await this.client.multipartUpload(newFileName, file, {
        progress: function(p, checkpoint) {
          that.percentage = parseFloat((p * 100).toFixed(2));
        }
      });
      if (that.percentage == 100) {
        that.dialogTableVisible = false;
      }
      let { origin, pathname } = new URL(requestUrls[0]);
      return origin + decodeURIComponent(pathname);
    },
    //批量上傳文件。返回成功上傳的url數(shù)組
    async addFiles() {
      let urls = [];
      if (this.fileList.length !== 0) {
        for (const item of this.fileList) {
          let { name, raw } = item;
          let pathname = await this.UploadImageVideo(name, raw);
          urls.push(pathname);
        }
      }
      return urls;
    },
    //更新文件數(shù)據(jù)。上傳新數(shù)據(jù)到服務(wù)器,并刪除服務(wù)器中的舊數(shù)據(jù),返回更新后的url數(shù)組
    async UpdateFiles() {
      let arr_newUploaded = []; //新上傳的圖片url。
      let arr_original = []; //原有的圖片url。不用刪除
      let arr_delete = []; //需要?jiǎng)h除的圖片url。
      if (this.fileList.length !== 0) {
        for (const { raw, name, url } of this.fileList) {
          //注意:這里一定要判斷raw是否存在。存在,則表示是新上傳的;不存在,則表示是原有的
          if (raw) {
            let pathname = await this.UploadImageVideo(name, raw);
            arr_newUploaded.push(pathname);
          }
          if (this.currentUrls.includes(url)) {
            arr_original.push(url);
          }
        }
      }
 
      for (const element of this.currentUrls) {
        if (!arr_original.includes(element)) {
          arr_delete.push(element);
        }
      }
      await this.deleteMultiFiles(arr_delete);
 
      return [...arr_original, ...arr_newUploaded];
    },
    //批量刪除服務(wù)器中的文件。參數(shù):待刪除到服務(wù)器文件url數(shù)組。
    async deleteMultiFiles(urls = []) {
      let arr_pathname = [];
      if (urls.length !== 0) {
        for (const item of urls) {
          //不要用let url=require("url");url.parse();已失效。要用new URL()
          let { pathname } = new URL(item);
          // decodeURIComponent()函數(shù)將中文亂碼轉(zhuǎn)為中文
          arr_pathname.push(decodeURIComponent(pathname));
        }
        //刪除服務(wù)器中的圖片
        await this.client.deleteMulti(arr_pathname);
      }
    }
  },
  watch: {}
};
</script>
 
<style lang="scss" scoped>
.UploadImageVideo {
  /*去除upload組件過(guò)渡效果*/
  ::v-deep .el-upload-list__item {
    transition: none !important;
  }
}
</style>

使用:

<UploadImageVideo
  ref="ref_UploadImageVideo"
  bucket="xxx"
  :currentUrls="formData.imgurl"
  :limitFileNumber="3"
  tip="1、最多上傳3張照片; 2、上傳圖片只能是 JPEG/JPG/PNG 格式; 3、單張圖片大小不能超過(guò) 5MB!"
  fileType="image"
  :isMultiple="true"
></UploadImageVideo>
  • fileType可選。默認(rèn)不寫,表示圖片、視頻都可上傳。fileType="image"表示只能上傳圖片。fileType="video"表示只能上傳視頻

  • bucket必選。

  • isMultiple可選。默認(rèn)為false

  • currentUrls必選。當(dāng)前目前已有的文件服務(wù)器url數(shù)組。通常新增文件時(shí),傳入的currentUrls為空數(shù)組[];更新文件時(shí),傳入到currentUrls為非空數(shù)組

  • tip可選。提示內(nèi)容

提供的方法:(當(dāng)前組件中所有的上傳都是批量上傳,且為分片上傳,以展示上傳進(jìn)度條)

  1. UpdateFiles()。更新文件數(shù)據(jù)。上傳新數(shù)據(jù)到服務(wù)器,并刪除服務(wù)器中的舊數(shù)據(jù),返回更新后的url數(shù)組

  2. addFiles()。批量上傳文件。返回成功上傳的url數(shù)組

  3. deleteMultiFiles(urls = [])。批量刪除服務(wù)器中的文件。參數(shù):待刪除到服務(wù)器文件url數(shù)組。

  4. UploadImageVideo(filename, file)。分片上傳數(shù)據(jù),可展示進(jìn)度條。上傳重命名后的文件到alioss, 并返回單個(gè)文件url字符串。可支持中文文件名

調(diào)用組件中的方法:例如可通過(guò) let urls = await this.$refs["ref_UploadImageVideo"].addFiles();調(diào)用批量上傳圖片或視頻的方法

例1:

怎么用Vue組件封裝上傳圖片和視頻怎么用Vue組件封裝上傳圖片和視頻 怎么用Vue組件封裝上傳圖片和視頻 

<!--userManage-->
<template>
  <div class="userManage">
    <el-card>
      <div >
        <el-input
          v-model="searchName"
          clearable
          placeholder="輸入用戶名稱搜索"
          
        />
        <el-button
          sizi="mini"
          type="success"
          icon="el-icon-search"
          @click="searchUser(searchName)"
        >搜索</el-button>
        <el-button
          sizi="mini"
          type="warning"
          icon="el-icon-refresh-left"
          @click="searchName = ''"
        >重置</el-button>
        <el-button sizi="mini" @click="handleAdd()" type="primary" icon="el-icon-plus">新增</el-button>
        <el-button @click="getUserList()" sizi="mini" icon="el-icon-refresh" >刷新</el-button>
      </div>
      <el-table :data="tableData" border v-loading="isLoading">
        <el-table-column label="用戶名" prop="username" align="center" width="150px"></el-table-column>
        <el-table-column label="密碼" prop="password" align="center"></el-table-column>
        <el-table-column label="圖片" align="center">
          <template slot-scope="scope">
            <div
              style="
                display: flex;
                justify-content: space-around;
                flex-flow: row wrap;
              "
            >
              <el-image
                
                v-for="(item, index) in scope.row.imgurl"
                :key="index"
                :src="item"
                :preview-src-list="scope.row.imgurl"
              ></el-image>
              <!-- <a :href="scope.row.imgurl" rel="external nofollow"  target="_blank">{{scope.row.imgurl}}</a> -->
            </div>
          </template>
        </el-table-column>
        <el-table-column label="操作" align="center">
          <template slot-scope="scope">
            <el-button size="mini" @click="showEditDialog(scope.row)">
              <i class="el-icon-edit" /> 編輯
            </el-button>
            <el-button size="mini" type="danger" @click="handleDelete(scope.row)">
              <i class="el-icon-delete" /> 刪除
            </el-button>
          </template>
        </el-table-column>
      </el-table>
    </el-card>
    <UserManageDialog :dialog="dialog" :formData="formData" @addUser="addUser" @editUser="editUser"></UserManageDialog>
  </div>
</template>
 
<script>
import UserManageDialog from "./userManageDialog.vue";
import { client_alioss, deleteMultiFiles } from "@/utils/alioss.js";
 
import {
  addUser,
  getUserList,
  editUser,
  deleteUser,
  searchUser
} from "@/api/userManage/index";
export default {
  name: "userManage",
  components: { UserManageDialog },
  data() {
    return {
      searchName: "",
      isLoading: false,
      dialog: {
        show: false,
        title: ""
      },
      formData: {},
      tableData: [
        {
          _id: "",
          username: "admin",
          password: "123",
          imgurl: []
        }
      ],
      currentImgs: []
    };
  },
  props: {},
  created() {},
  mounted() {
    this.getUserList();
  },
  computed: {},
  methods: {
    //獲取用戶列表
    async getUserList() {
      this.isLoading = true;
      let { data } = await getUserList();
      this.tableData = data.data;
      this.isLoading = false;
    },
 
    //打開新增用戶窗口
    handleAdd() {
      this.dialog = {
        show: true,
        title: "新增用戶",
        option: "add"
      };
      this.formData = {
        username: "",
        password: "",
        imgurl: []
      };
    },
    //打開編輯用戶窗口
    showEditDialog(row) {
      this.currentImgs = row.imgurl;
 
      this.dialog = {
        show: true,
        title: "編輯用戶",
        option: "edit"
      };
      this.formData = {
        _id: row._id,
        username: row.username,
        password: row.password,
        imgurl: row.imgurl
      };
    },
    //新增用戶
    async addUser(urls) {
      this.formData.imgurl = urls;
 
      await addUser(this.formData);
      this.dialog.show = false;
      this.$notify({
        title: "成功",
        message: "新增用戶成功!",
        type: "success"
      });
      this.getUserList();
    },
    //編輯用戶
    async editUser(urls) {
      this.formData.imgurl = urls;
 
      await editUser(this.formData, this.formData._id); //更新數(shù)據(jù)庫(kù),尤其是圖片url
 
      this.dialog.show = false;
      this.$notify({
        title: "成功",
        message: "編輯用戶成功!",
        type: "success"
      });
      this.getUserList();
    },
    //刪除用戶
    handleDelete({ _id }) {
      this.$confirm("此操作將永久刪除該文件, 是否繼續(xù)?", "提示", {
        confirmButtonText: "確定",
        cancelButtonText: "取消",
        type: "warning"
      })
        .then(async () => {
          this.$message({
            type: "success",
            message: "刪除成功!",
            showClose: true
          });
          let {
            data: { imgurl }
          } = await deleteUser(_id);
 
          //刪除服務(wù)器中的文件。傳入待刪除的url數(shù)組
          await deleteMultiFiles(imgurl);
 
          this.getUserList();
        })
        .catch(() => {
          this.$message({
            type: "info",
            message: "已取消刪除",
            showClose: true
          });
        });
    },
    //根據(jù)用戶名查詢
    async searchUser(searchName) {
      this.isLoading = true;
      let { data } = await searchUser({
        searchName
      });
      this.tableData = data.data;
      this.isLoading = false;
    }
  },
  watch: {}
};
</script>
 
<style lang="scss" scoped>
.userManage {
}
</style>

 怎么用Vue組件封裝上傳圖片和視頻

<!--userManageDialog   -->
<template>
  <div class="userManageDialog">
    <el-dialog :title="dialog.title" width="45%" :visible.sync="dialog.show" v-if="dialog.show">
      <el-form ref="ref_form_userManage" :model="formData" :rules="rules" label-width="100px">
        <el-form-item label="用戶名" prop="username">
          <el-input v-model="formData.username" autocomplete="off" ></el-input>
        </el-form-item>
        <el-form-item label="密碼" prop="password">
          <el-input v-model="formData.password" autocomplete="off" ></el-input>
        </el-form-item>
        <el-form-item label="圖片" prop="imgurl">
          <!-- fileType屬性不寫的話,表示圖片、視頻都可上傳。fileType="image"表示只能上傳圖片。fileType="video"表示只能上傳視頻 -->
          <UploadImageVideo
            ref="ref_UploadImageVideo"
            bucket="bucket-lijiang-test"
            :currentUrls="formData.imgurl"
            :limitFileNumber="3"
            tip="1、最多上傳3張照片; 2、上傳圖片只能是 JPEG/JPG/PNG 格式; 3、單張圖片大小不能超過(guò) 5MB!"
            fileType="image"
            :isMultiple="true"
          ></UploadImageVideo>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="dialog.show = false">取 消</el-button>
        <el-button
          v-if="dialog.option == 'add'"
          @click="addUser('ref_form_userManage')"
          type="primary"
        >確 定</el-button>
        <el-button
          v-if="dialog.option == 'edit'"
          @click="editUser('ref_form_userManage')"
          type="primary"
        >確 定</el-button>
      </div>
    </el-dialog>
  </div>
</template>
 
<script>
import UploadImageVideo from "@/components/UploadImageVideo";
 
export default {
  name: "userManageDialog",
  components: { UploadImageVideo },
  props: ["dialog", "formData"],
  data() {
    return {
      fileList: [],
      rules: {
        username: [
          { required: true, message: "請(qǐng)輸入用戶名稱", trigger: "blur" }
        ]
      }
    };
  },
  created() {},
  mounted() {},
  computed: {},
  methods: {
    addUser(formName) {
      this.$refs[formName].validate(async valid => {
        if (valid) {
          let urls = await this.$refs["ref_UploadImageVideo"].addFiles();
          this.$emit("addUser", urls);
        } else {
          console.log("error submit!!");
          return false;
        }
      });
    },
    editUser(formName) {
      this.$refs[formName].validate(async valid => {
        if (valid) {
          let urls = await this.$refs["ref_UploadImageVideo"].UpdateFiles();
 
          this.$emit("editUser", urls);
        } else {
          console.log("error submit!!");
          return false;
        }
      });
    }
  },
  watch: {}
};
</script>
<style lang="scss" scoped>
</style>

 怎么用Vue組件封裝上傳圖片和視頻

import { uuid } from 'vue-uuid';
const OSS = require("ali-oss");
 
let client = new OSS({
    region: "oss-cn-chengdu",
    accessKeyId: "LTAI5tQPHvixV8aakp1vg8Jr",
    accessKeySecret: "xYyToToPe8UFQMdt4hpTUS4PNxzl9S",
    bucket: "bucket-lijiang-test",
 
});
 
export const client_alioss = client;
 
 
//刪除文件數(shù)組
export async function deleteMultiFiles(urls = []) {
    let arr_pathname = [];
    if (urls.length !== 0) {
        for (const item of urls) {
            //不要用let url=require("url");url.parse();已失效。要用new URL()
            let { pathname } = new URL(item);
            // decodeURIComponent()函數(shù)將中文亂碼轉(zhuǎn)為中文
            arr_pathname.push(decodeURIComponent(pathname));
        }
        await client.deleteMulti(arr_pathname);
    }
}

 怎么用Vue組件封裝上傳圖片和視頻

import request from '@/utils/request'
//  獲取用戶列表
export function getUserList() {
    return request({
        url: '/api/userManage',
        method: 'get'
    })
}
 
//  新增用戶
export function addUser(data) {
    return request({
        url: '/api/userManage',
        method: 'post',
        data
    })
}
 
//  編輯用戶
export function editUser(data, _id) {
    return request({
        url: `/api/userManage/${_id}`,
        method: 'put',
        data
    })
}
 
//  刪除用戶
export function deleteUser(_id) {
    return request({
        url: `/api/userManage/${_id}`,
        method: 'delete'
    })
}
 
//  根據(jù)關(guān)鍵字查詢
export function searchUser(data) {
    return request({
        url: `/api/userManage/search`,
        method: 'get',
        params: data
    })
}

怎么用Vue組件封裝上傳圖片和視頻  

const router = require('koa-router')()
 
const User = require("../models/User"); //引入模塊模型
router.prefix('/userManage')
 
//獲取用戶列表
router.get('/', async (ctx, next) => {
    let data = await User.find({})
    ctx.body = {
        code: 200,
        message: "請(qǐng)求成功",
        data,
    }
})
//新增用戶
router.post('/', async (ctx, next) => {
    let { username, password, imgurl } = ctx.request.body;
    await User.create({ username, password, imgurl })
    ctx.body = { code: 200, message: "新增成功" }
})
//編輯用戶
router.put('/:_id', async (ctx, next) => {
    let { username, password, imgurl } = ctx.request.body;
    let { _id } = ctx.params
 
    await User.findByIdAndUpdate(_id, { username, password, imgurl })
    ctx.body = { code: 200, message: "編輯成功" }
})
//刪除用戶
router.delete('/:_id', async (ctx, next) => {
    let { _id } = ctx.params;
    let { imgurl } = await User.findByIdAndDelete(_id)
    ctx.body = { code: 200, message: "刪除成功", imgurl }
 
})
 
//根據(jù)關(guān)鍵字查詢用戶。模糊查詢
 
router.get('/search', async (ctx, next) => {
    let { searchName } = ctx.request.query;
 
    let data = await User.find({ username: { $regex: searchName } })
    ctx.body = { code: 200, message: "查詢成功", data }
})
module.exports = router

到此,關(guān)于“怎么用Vue組件封裝上傳圖片和視頻”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實(shí)踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識(shí),請(qǐng)繼續(xù)關(guān)注億速云網(wǎng)站,小編會(huì)繼續(xù)努力為大家?guī)?lái)更多實(shí)用的文章!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

vue
AI