vue3+elementPlus+vueCropper实现头像(图片)裁剪(非常全,可直接cv!!!!!)

写下这篇文章缘由是做这个功能属实是踩了很多坑...

话不多说,开讲!

引入vueCropper插件

// 安装
npm install vue-cropper@next
// 或者
yarn add vue-cropper@next
// 在页面引入
import "vue-cropper/dist/index.css";
import { VueCropper } from "vue-cropper";

elementPlus的上传组件

这里一个上传组件一个没有头像时候的默认头像,可以只复制el-upload的代码

<div
        class="avatar flex-center-center"
        @mouseenter="isShowAvatar = -1"
        @mouseleave="isShowAvatar = 0"
      >
        <el-upload
          class=""
          :headers="headers"
          :auto-upload="false"
          action=""
          :on-change="changeSize"
          accept=".jpg,.png"
          :on-success="onImageSuccess"
          :on-error="onImageError"
          v-if="isShowAvatar && userInfo.id == formData.id"
        >
          <div
            class="modify-avatar tac cp"
            :style="`background-color: ${themeColor};`"
          >
            <el-icon
              :size="25"
              color="#fff"
            >
              <Camera />
            </el-icon>
          </div>
        </el-upload>
        <el-avatar
          v-else
          :size="100"
          :src="!userInfo.avatar ? 'https://cube.elemecdn.com/0/88/03b0d39583f48206768a7534e55bcpng.png' 
        : userInfo.avatar.includes('http')?userInfo.avatar:userInfo.baseURL+userInfo.avatar "
        ></el-avatar>
      </div>

现在进入正题,上图片裁剪代码

html部分,这是一个el-dialog弹窗

<!-- 头像裁剪弹窗 -->
    <el-dialog
      v-model="centerDialogVisible"
      title="裁剪头像"
      width="60%"
      align-center
    >
      <div class="cropper-content">
        <div
          class="cropper"
          style="text-align:center"
        >
          <vueCropper
            ref="cropper"
            :img="option.img"
            :outputSize="option.size"
            :outputType="option.outputType"
            :info="true"
            :full="option.full"
            :canMove="option.canMove"
            :canMoveBox="option.canMoveBox"
            :original="option.original"
            :autoCrop="option.autoCrop"
            :fixed="option.fixed"
            :fixedNumber="option.fixedNumber"
            :centerBox="option.centerBox"
            :infoTrue="option.infoTrue"
            :fixedBox="option.fixedBox"
            :autoCropWidth="option.autoCropWidth"
            :autoCropHeight="option.autoCropHeight"
          />
          <div class="handle_btn">
            <el-button
              type="primary"
              plain
              @click="changeScale(1)"
            >+ 放大</el-button>
            <el-button
              type="primary"
              plain
              @click="changeScale(-1)"
            >- 缩小</el-button>
            <el-button
              type="primary"
              plain
              @click="rotateLeft"
            >↺ 左旋转</el-button>
            <el-button
              type="primary"
              plain
              @click="rotateRight"
            >↻ 右旋转</el-button>
          </div>

        </div>
      </div>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="centerDialogVisible = false">取消</el-button>
          <el-button
            type="primary"
            @click="uploadAvatar"
          > 确认 </el-button>
        </span>
      </template>
    </el-dialog>

数据层

// 头像裁剪
const centerDialogVisible = ref(false);
//获取裁剪图片组件
const cropper = ref();
// 头像裁剪各项参数
const option = reactive({
  img: "", // 裁剪图片的地址
  info: true, // 裁剪框的大小信息
  outputSize: 1, // 裁剪生成图片的质量
  outputType: "jpg", // 裁剪生成图片的格式
  canScale: true, // 图片是否允许滚轮缩放
  autoCrop: true, // 是否默认生成截图框
  canMoveBox: true, // 截图框能否拖动
  autoCropWidth: 200, // 默认生成截图框宽度
  autoCropHeight: 200, // 默认生成截图框高度
  fixedBox: false, // 固定截图框大小 不允许改变
  fixed: true, // 是否开启截图框宽高固定比例
  fixedNumber: [1, 1], // 截图框的宽高比例
  full: false, // 是否输出原图比例的截图
  original: false, // 上传图片按照原始比例渲染
  centerBox: false, // 截图框是否被限制在图片里面
  infoTrue: true, // true 为展示真实输出图片宽高 false 展示看到的截图框宽高
});

css

.cropper-content {
  .cropper {
    width: auto;
    height: 350px;
    .handle_btn {
      display: flex;
      display: -webkit-flex;
      justify-content: space-between;
      padding: 10px 300px;
      box-sizing: border-box;
    }
  }
}

现在就开始处理全部逻辑了

首先是el-upload的change事件,这一步一定要做,卡住了我很久...如果不将得到的文件url转换成base64,只要给option.img赋值就会报CORS跨域,还有一点el-upload里面的action一定不要写上传地址,不然也会也有报错

const changeSize = (UploadFile) => {
  centerDialogVisible.value = true;
  //这里将图片转化为base64位格式为图片进行裁剪
  const reader = new FileReader();
  reader.onload = (e) => {
    //将图片绑定到裁剪组件的img中
    option.img = e.target.result;
  };
  //拿到图片的base64
  reader.readAsDataURL(UploadFile.raw);
};

最后一步就是确认裁剪操作了,这一步一定要用asyncawait,不然数据获取的会有问题,会显示promisepending,调上传接口的时候也要把headers带上,点击确认裁剪的时候我加了一个elementplus的loading动画,防止没上传完弹出就被用户x掉了

// 点击确认
const uploadAvatar = () => {
  isLoading.value = true;
  //上传头像并且点击了确认按钮 异步才能获取数据
  cropper.value.getCropBlob(async (data) => {
    let formData = new FormData();
    formData.append("file", data, "avatar.jpg");
    const res = await axios({
      method: "post",
      headers: {
        "Access-Control-Allow-Origin": "*",
        token: getToken(),
      }, // 请求头      
      url: "/api/set/upload", //请求地址
      data: formData,
    });
    if (res.data.code == 1) {
      isLoading.value = false;
      saveAvatar({ avatar: res.data.data.fullurl }).then((res2) => {
        centerDialogVisible.value = false;
        if (res2.data.code == 1) {
          ElMessage.success("修改成功");
          getBriefInfo();
          isShowAvatar.value = 0;
          userInfo.avatar = res.data.data.fullurl;
        } else {
          ElMessage.error("上传图片错误,请稍后重试");
        }
      });
    } else {
      isLoading.value = false;
    }
  });
};

附加一个放大缩小旋转的小功能

//图片缩放
const changeScale = (num) => {
  num = num || 1;
  cropper.value.changeScale(num);
};
//向左旋转
const rotateLeft = () => {
  cropper.value.rotateLeft();
};
//向右旋转
const rotateRight = () => {
  cropper.value.rotateRight();
};

loading动画,标签根部

数据层定义

let isLoading = ref(false);

总结:首先使用el-upload拿到图片地址,将图片url转换成base64,使用头像裁剪,最后调用upload上传接口,成功后调用保存图片即可

完结,撒花,以上代码有任何问题请私信踢我,或者评论区留言!!!!!!!!!!!

  • 8
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
通过Vue3和Element Plus来实现商城首页,你可以按照以下步骤进行: 1. 安装VueElement Plus 首先,在项目安装VueElement Plus。你可以通过npm或者yarn来进行安装。使用以下命令来安装VueElement Plus: ``` npm install vue@next npm install element-plus ``` 2. 创建Vue实例 在入口文件,创建Vue实例,并将Element Plus导入Vue实例,例如: ```javascript import { createApp } from 'vue'; import ElementPlus from 'element-plus'; import 'element-plus/dist/index.css'; import App from './App.vue'; const app = createApp(App); app.use(ElementPlus); app.mount('#app'); ``` 3. 创建商城首页组件 在components文件夹创建一个名为Home.vue的组件,该组件将作为商城首页的容器。在该组件,你可以使用Element Plus提供的组件来构建你的页面布局和样式。 4. 在Home.vue引入Element Plus组件 在Home.vue文件,使用如下代码引入Element Plus的组件: ```javascript <template> <el-container> <el-header>Header</el-header> <el-main>Main</el-main> <el-footer>Footer</el-footer> </el-container> </template> ``` 可以根据你的需求添加其他Element Plus组件,如Menu、Carousel等等。 5. 在App.vue使用商城首页组件 在App.vue使用Home.vue组件来展示商城首页。在App.vue的template,添加以下代码: ```javascript <template> <div> <Home/> </div> </template> <script> import Home from './components/Home.vue'; export default { components: { Home } } </script> ``` 6. 运行项目 现在,你可以运行你的项目,通过浏览器查看商城首页。使用以下命令来运行项目: ``` npm run serve ``` 以上就是使用Vue3和Element Plus实现商城首页的基本步骤。你可以根据自己的需求进一步完善和定制商城首页的界面设计和功能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

 冰紫露恋蝶玛丽红红秃头宝贝

你的鼓励是我最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值