最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

vue3+ElementPlus+VueCropper實現(xiàn)上傳圖片功能

 更新時間:2025年01月14日 09:58:18   作者:An_s  
文章介紹了如何在Vue3、ElementPlus和VueCropper組件中實現(xiàn)圖片上傳和裁剪功能,包括放大、縮小等操作,感興趣的朋友跟隨小編一起看看吧

前言

我們需要上傳圖片,然后彈框進行裁剪(放大、縮?。?。

效果

實現(xiàn)

裁剪組件.vue

<template>
    <div>
        <!--裁剪圖片-->
        <el-dialog v-model="tailorDialogVisible" @open="onTailorDialogOpen" @close="onTailorDialogCancel" title="編輯圖片" width="680" align-center>
            <div style=" width: 550px; height: 450px; margin: 30px auto;" v-loading="loading"
                 element-loading-text="Loading...">
                <vue-cropper ref="cropper"
                             :img="tailorOption.img"
                             :output-type="tailorOption.outputType"
                             :full="tailorOption.full"
                             :auto-crop="tailorOption.autoCrop"
                             :auto-crop-width="tailorOption.autoCropWidth"
                             :auto-crop-height="tailorOption.autoCropHeight"
                             :center-box="tailorOption.centerBox"
                             :max-img-size="tailorOption.max"
                             mode="cover"
                             @imgLoad="onTailorLoad"
                ></vue-cropper>
            </div>
            <div style="display: flex; margin: 0 200px; justify-content: center; align-items: center">
                <div style="width: 40px;text-align: left; cursor: pointer;">
                    <!-- <el-icon @click="onScaleMinus(0.1)" :size="16"><Minus /></el-icon> -->
                    <span @click="onScaleMinus(0.1)">-號</span>
                </div>
                <div style="flex: 1">
                    <el-slider v-model="tailorAmplificationValue" :min="1" :max="3" :step="0.1" @change="onChangTailorAmplificationSlider" />
                </div>
                <div style="width: 40px;text-align: right; cursor: pointer;">
                    <!-- <el-icon @click="onScaleAdd(0.1)" :size="16"><Plus /></el-icon> -->
                    <span @click="onScaleAdd(0.1)">+號</span>
                </div>
            </div>
            <div style="display: flex; margin: 10px 200px 40px 200px; justify-content: center; align-items: center">
                <div style="width: 40px;text-align: left; cursor: pointer;">
                  <span @click="onRotateLeft">左旋</span>
                  <!-- <el-icon @click="onRotateLeft" :size="16"><Plus /></el-icon> -->
                    <!-- <img @click="onRotateLeft" style="width: 14px; height: 14px" src="../../../public/img/recipeManage/left_rotate.png" alt=""> -->
                </div>
                <div style="flex: 1">
                    <el-slider v-model="tailorSpinValue" :min="-180" :max="180" :step="90" @change="onChangTailorSpinSlider" />
                </div>
                <div style="width: 40px;text-align: right; cursor: pointer;">
                  <span @click="onRotateRight">右旋</span>
                  <!-- <el-icon @click="onRotateRight" :size="16"><Plus /></el-icon> -->
                    <!-- <img @click="onRotateRight" style="width: 14px; height: 14px" src="../../../public/img/recipeManage/right_rotate.png" alt=""> -->
                </div>
            </div>
            <div style="padding-top: 20px;" class="recipeManage_border_top">
                <div style="display: flex; align-items: center; justify-content: center">
                    <div>
                        <el-button type="primary" plain @click="onTailorDialogCancel">取消</el-button>
                    </div>
                    <div style="margin-left: 20px">
                        <el-button type="primary" @click="onTailorDialogSubmit">確認</el-button>
                    </div>
                </div>
            </div>
        </el-dialog>
    </div>
</template>
<script setup>
  import 'vue-cropper/dist/index.css'
  import { VueCropper }  from "vue-cropper";
  // import { postImgData } from '@/api/base/public';
  import { ref, defineProps, toRefs, defineEmits } from 'vue';
  const emit = defineEmits(['close', 'submit']);
  const props = defineProps({
    tailorDialogImg: {
      default: ''
    },
    autoCropWidth: {
      default: 180
    },
    autoCropHeight: {
      default: 180
    },
    tailorDialogVisible: {
      type: Boolean,
      required: true,
      default: false
    },
  });
  const { tailorDialogVisible, tailorDialogImg, autoCropWidth, autoCropHeight } = toRefs(props);
  const loading = ref(false);
  // 裁剪圖片
  const cropper = ref("");
  // const tailorDialogVisible = ref(visible.value);
  const tailorAmplificationValue = ref(0);
  const tailorSpinValue = ref(0);
  const tailorOption =  ref({
    img: "",
    full: false,
    outputType: 'png',
    autoCrop: true,
    autoCropWidth: 180,
    autoCropHeight: 180,
    centerBox: true,
    max: 99999,
  });
  // 放大
  let oldTailorAmplificationValue = 0;
  const onScaleAdd = (num) => {
    if (tailorAmplificationValue.value === 3) return;
    // tailorAmplificationValue.value = Number(parseFloat(tailorAmplificationValue.value + num).toFixed(1));
    tailorAmplificationValue.value = +(parseFloat(tailorAmplificationValue.value + num).toFixed(1));
    oldTailorAmplificationValue = tailorAmplificationValue.value;
    cropper.value.changeScale(tailorAmplificationValue.value);
  };
  const onScaleMinus = (num) =>  {
    if (tailorAmplificationValue.value === 1) return;
    tailorAmplificationValue.value = tailorAmplificationValue.value - num;
    oldTailorAmplificationValue = -tailorAmplificationValue.value;
    cropper.value.changeScale(-tailorAmplificationValue.value);
  };
  const onChangTailorAmplificationSlider = (value) => {
    if (oldTailorAmplificationValue > value) {
      cropper.value.changeScale(-value);
    } else {
      cropper.value.changeScale(value);
    }
    oldTailorAmplificationValue = value;
  };
  // 旋轉
  let oldTailorRotateValue = 0;
  const onChangTailorSpinSlider = (value) => {
    if (value > 0) {
      cropper.value.rotateRight();
    } else {
      cropper.value.rotateLeft();
    }
  };
  const onRotateLeft = () => {
    if (cropper.value.rotate === -2) return false;
    cropper.value.rotateLeft();
    oldTailorRotateValue = cropper.value.rotate * 90
    console.log("===oldTailorRotateValue===", oldTailorRotateValue)
    tailorSpinValue.value = cropper.value.rotate * 90
  };
  const onRotateRight = () =>  {
    if (cropper.value.rotate === 2) return false;
    cropper.value.rotateRight();
    oldTailorRotateValue = cropper.value.rotate * 90
    console.log("===oldTailorRotateValue===", oldTailorRotateValue)
    tailorSpinValue.value = cropper.value.rotate * 90
  };
  const onTailorDialogOpen = () => {
    console.log("===彈框打開===");
    loading.value = true;
    tailorOption.value.img = tailorDialogImg.value;
    tailorOption.value.autoCropWidth = autoCropWidth.value;
    tailorOption.value.autoCropHeight = autoCropHeight.value;
  };
  const onTailorLoad = (msg) => {
    console.log("===msg===", msg)
    loading.value = false;
  };
  const onTailorDialogCancel = () => {
    emit('close');
    loading.value = false;
    tailorOption.value.img = "";
    tailorAmplificationValue.value = 0;
    tailorSpinValue.value = 0;
  };
  const onTailorDialogSubmit = () => {
    cropper.value.getCropData(data => {
      tailorAmplificationValue.value = 0;
      tailorSpinValue.value = 0;
      tailorOption.value.img = "";
      emit('submit', data);
    })
    // cropper.value.getCropBlob(data => {
    //   // 創(chuàng)建 FormData 對象并添加 Blob 對象
    //   const formData = new FormData();
    //   formData.append('file', data, '1.png');
    //   // postImgData(formData).then((res) => {
    //   //   if (res.data.code === 200) {
    //   //     emit('submit', res.data.data);
    //   //   }
    //   // }).catch(err => {});
    //   tailorAmplificationValue.value = 0;
    //   tailorSpinValue.value = 0;
    //   tailorOption.value.img = "";
    //   emit('submit', '');
    // })
    // let blob = await cropper.value.getCropBlob();
    // // 創(chuàng)建 FormData 對象并添加 Blob 對象
    // const formData = new FormData();
    // formData.append('file', blob, '1.png');
    // let res = postImgData(formData);
    //
    // emit('submit', res.data.data);
    //
    // tailorAmplificationValue.value = 0;
    // tailorSpinValue.value = 0;
    // tailorOption.value.img = "";
  };
</script>
<style>
</style>

使用組件.vue

<template>
  <div>
    <el-upload action="#" :http-request="onImgRequest" :show-file-list="false" :before-upload="(file) => onImgUpload(file)">
      <div style="height: 100px; width: 100px; background-color: red;">上傳</div>
    </el-upload>
    <el-image v-if="imagesUrl" :src="imagesUrl"></el-image>
     <tailorImage :tailorDialogVisible="tailorDialogVisible" :tailorDialogImg="tailorDialogImg" @submit="tailorDialogImgSucc"></tailorImage>
     <!-- <el-image :src="src" /> -->
  </div>
</template>
<script setup>
import tailorImage from "./components/TailorImage.vue"
import {ref} from "vue"
import { ElMessage } from 'element-plus';
const tailorDialogVisible = ref(false)
const tailorDialogImg = ref("")
const imagesUrl = ref("")
const onImgRequest = () => {};
const onImgUpload = (rawFile) => {
  if (rawFile.type.indexOf('image/') === -1) {
    ElMessage.error('文件格式錯誤,請上傳圖片類型,如: JPG,PNG后綴的文件');
    return false;
  } else {
    const reader = new FileReader();
    reader.readAsDataURL(rawFile);
    reader.onload = () => {
      tailorDialogImg.value = reader.result;
      tailorDialogVisible.value = true;
    };
  }
};
const tailorDialogImgSucc = (data) => {
  // console.log("===tailorDialogImgSucc===", data)
  imagesUrl.value = data;
  tailorDialogVisible.value = false;
  tailorDialogImg.value = "";
}
// const test = () => {
//   tailorDialogVisible.value = true
//   console.log("===裁剪圖片====");
// }
</script>
<style>
</style>

到此這篇關于vue3+ElementPlus+VueCropper實現(xiàn)上傳圖片的文章就介紹到這了,更多相關vue3 ElementPlus VueCropper上傳圖片內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • vue大數(shù)據表格卡頓問題的完美解決方案

    vue大數(shù)據表格卡頓問題的完美解決方案

    這篇文章主要給大家介紹了基于vue大數(shù)據表格卡頓問題的完美解決方案,文中通過示例代碼介紹的非常詳細,對大家學習或者使用vue具有一定的參考學習價值,需要的朋友們下面來一起學習學習吧
    2019-03-03
  • vue router動態(tài)路由下讓每個子路由都是獨立組件的解決方案

    vue router動態(tài)路由下讓每個子路由都是獨立組件的解決方案

    這篇文章主要介紹了vue router動態(tài)路由下讓每個子路由都是獨立組件的解決方案,非常不錯,具有參考借鑒價值,需要的朋友可以參考下
    2018-04-04
  • vue設置全局訪問接口API地址操作

    vue設置全局訪問接口API地址操作

    這篇文章主要介紹了vue設置全局訪問接口API地址操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-08-08
  • Vue關于對象直接賦值的坑及解決

    Vue關于對象直接賦值的坑及解決

    這篇文章主要介紹了Vue關于對象直接賦值的坑及解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-09-09
  • 基于element-ui封裝表單金額輸入框的方法示例

    基于element-ui封裝表單金額輸入框的方法示例

    這篇文章主要介紹了基于element-ui封裝表單金額輸入框的方法示例,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2021-01-01
  • vue2.0 與 bootstrap datetimepicker的結合使用實例

    vue2.0 與 bootstrap datetimepicker的結合使用實例

    本篇文章主要介紹了vue2.0 與 bootstrap datetimepicker的結合使用實例,非常具有實用價值,需要的朋友可以參考下
    2017-05-05
  • vue實現(xiàn)文件上傳

    vue實現(xiàn)文件上傳

    這篇文章主要為大家詳細介紹了vue實現(xiàn)文件上傳功能,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-04-04
  • vue實現(xiàn)移動端懸浮窗效果

    vue實現(xiàn)移動端懸浮窗效果

    這篇文章主要為大家詳細介紹了vue實現(xiàn)移動端懸浮窗效果,vuejs實現(xiàn)div拖拽移動,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-12-12
  • vue.js動態(tài)設置VueComponent高度遇到的問題及解決

    vue.js動態(tài)設置VueComponent高度遇到的問題及解決

    這篇文章主要介紹了vue.js動態(tài)設置VueComponent高度遇到的問題及解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-08-08
  • 使用Vue實現(xiàn)調用接口加載頁面初始數(shù)據

    使用Vue實現(xiàn)調用接口加載頁面初始數(shù)據

    今天小編就為大家分享一篇使用Vue實現(xiàn)調用接口加載頁面初始數(shù)據,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-10-10

最新評論

泸定县| 芜湖市| 石门县| 宁晋县| 靖宇县| 建宁县| 哈密市| 房产| 碌曲县| 东丰县| 竹北市| 阿城市| 汶川县| 阳西县| 通山县| 怀化市| 龙游县| 佳木斯市| 镇平县| 绥滨县| 武安市| 丹棱县| 土默特左旗| 鸡西市| 西充县| 德安县| 类乌齐县| 广河县| 安义县| 旬邑县| 保康县| 普陀区| 南川市| 柯坪县| 耒阳市| 本溪| 进贤县| 三原县| 鄂托克前旗| 琼海市| 庄河市|