您现在的位置是:首页 > 编程语言学习 > 前端编程语言 > 文章正文 前端编程语言
vue3 el-upload+vue-cropper 实现头像裁剪上传
2022-12-14 11:57:23 前端编程语言
简介最近遇到一个头像裁剪上传需求,项目是vue3为框架的。大家先来看效果图吧! 以下以vue3为例第一步 vue-cropper的引入npminstallvue-cro...
最近遇到一个头像裁剪上传需求,项目是vue3为框架的。大家先来看效果图吧!
以下以vue3为例
第一步 vue-cropper的引入
- npm install vue-cropper@next
页面组件中
- import 'vue-cropper/dist/index.css'
- import { VueCropper } from "vue-cropper";
第二步接下来直接上我封装的组件代码
***伙伴们拿着用
- <template>
- <el-dialog
- title="上传头像"
- v-model="dialogVisible"
- :show-close="false"
- :close-on-click-modal="false"
- :close-on-press-escape="false"
- destroy-on-close
- width="600px"
- >
- <div class="avatar-container">
- <!-- {{dialogVisible}} -->
- <!-- 待上传图片 -->
- <div v-show="!options.img" >
- <el-upload
- class="upload"
- ref="elUpload"
- action="#"
- :on-change="upload"
- accept="image/png, image/jpeg, image/jpg"
- :show-file-list="false"
- :auto-upload="false"
- >
- <el-button slot="trigger" type="primary" ref="uploadBtn">
- 选择图片
- </el-button>
- </el-upload>
- <div>支持jpg、png格式的图片,大小不超过5M</div>
- </div>
- <!-- <img :src="options.img" alt=""> -->
- <!-- 已上传图片 -->
- <div v-show="options.img" class="avatar-crop">
- <vueCropper
- class="crop-box"
- ref="cropper"
- :img="options.img"
- :autoCrop="options.autoCrop"
- :fixedBox="options.fixedBox"
- :canMoveBox="options.canMoveBox"
- :autoCropWidth="options.autoCropWidth"
- :autoCropHeight="options.autoCropHeight"
- :centerBox="options.centerBox"
- :fixed="options.fixed"
- :fixedNumber="options.fixedNumber"
- :canMove="options.canMove"
- :canScale="options.canScale"
- ></vueCropper>
- </div>
- </div>
- <template #footer>
- <span class="dialog-footer">
- <div class="reupload" @click="reupload">
- <span v-show="options.img">重新上传</span>
- </div>
- <div>
- <el-button @click="closeDialog">取 消</el-button>
- <el-button type="primary" @click="getCrop">确 定</el-button>
- </div>
- </span>
- </template>
- </el-dialog>
- </template>
- <script lang="ts" >
- import {ref,reactive,defineComponent} from "vue"
- import { VueCropper } from 'vue-cropper'
- import 'vue-cropper/dist/index.css'
- import type { UploadProps, UploadUserFile } from 'element-plus'
- import {
- ElMessage
- } from 'element-plus'
- export default defineComponent({
- props: {
- dialogVisible: {
- type: Boolean,
- }
- },
- components:{
- VueCropper
- },
- setup(props, { emit }) {
- // console.log(11111);
- const cropper=ref()
- const uploadBtn=ref()
- const elUpload=ref()
- const options=reactive({
- img: '', // 原图文件
- autoCrop: true, // 默认生成截图框
- fixedBox: false, // 固定截图框大小
- canMoveBox: true, // 截图框可以拖动
- autoCropWidth: 200, // 截图框宽度
- autoCropHeight: 200, // 截图框高度
- fixed: true, // 截图框宽高固定比例
- fixedNumber: [1, 1], // 截图框的宽高比例
- centerBox: true, // 截图框被限制在图片里面
- canMove: false, // 上传图片不允许拖动
- canScale: false // 上传图片不允许滚轮缩放
- })
- // vueCropper组件 裁剪配置信息
- // 读取原图
- const upload: UploadProps['onChange'] = (file, uploadFiles) => {
- console.log(file);
- const isIMAGE = file.raw.type === 'image/jpeg' || file.raw.type === 'image/png'
- const isLt5M = file.raw.size / 1024 / 1024 < 5
- if (!isIMAGE) {
- ElMessage.warning("请选择 jpg、png 格式的图片" );
- return false
- }
- if (!isLt5M) {
- ElMessage.warning("图片大小不能超过 5MB" );
- return false
- }
- let reader = new FileReader()
- reader.readAsDataURL(file.raw)
- console.log(reader);
- reader.onload = e => {
- options.img = e.target.result // base64
- }
- elUpload.value.clearFiles(); //这里处理重新上传时,upload组件change事件错误问题
- }
- // 获取截图信息
- const getCrop=()=> {
- // 获取截图的 base64 数据
- cropper.value.getCropData((data) => {
- // console.log(data);
- });
- // 获取截图的 blob 数据
- console.log(cropper.value);
- cropper.value.getCropBlob(data => {
- // console.log(111);
- console.log(data);
- // emit('closeAvatarDialog')
- closeDialog()
- })
- }
- // 重新上传
- const reupload=()=> {
- // console.log(uploadBtn.value.ref);
- uploadBtn.value.ref.click()
- }
- // 关闭弹框
- const closeDialog=()=> {
- emit('closeAvatarDialog')
- options.img = ''
- }
- return {
- options,
- cropper,
- uploadBtn,
- elUpload,
- upload,
- getCrop,
- reupload,
- closeDialog
- }
- }
- })
- </script>
- <style lang="scss" scoped>
- .dialog-footer {
- display: flex;
- justify-content: space-between;
- align-items: center;
- font-size: 14px;
- .reupload {
- color: #409eff;
- cursor: pointer;
- }
- }
- .avatar-container {
- display: flex;
- justify-content: center;
- align-items: center;
- width: 560px;
- height: 350px;
- background-color: #f0f2f5;
- margin-right: 10px;
- border-radius: 4px;
- .upload {
- text-align: center;
- margin-bottom: 24px;
- }
- .avatar-crop {
- width: 560px;
- height: 350px;
- position: relative;
- .crop-box {
- width: 100%;
- height: 100%;
- border-radius: 4px;
- overflow: hidden;
- }
- }
- }
- </style>
可以根据自己需要获取获取截图内容
获取截图的 base64 数据
- cropper.value.getCropData(data => {
- // do something
- console.log(data)
- })
- 获取截图的 blob 数据
- cropper.value.getCropBlob(data => {
- // do something
- console.log(data)
- })
第三步 使用封装得组件
- <template>
- <AvatarCropper v-if="dialogVisible" :dialogVisible.sync="dialogVisible" @closeAvatarDialog="closeAvatarDialog"></AvatarCropper>
- //这里还是用了v-if来进行组件的销毁与创建,来解决一些不必要的问题
- </template>
- <script lang="ts" setup>
- import {ref,reactive,} from "vue";
- import AvatarCropper from '@/components/avatarCropper.vue'
- const dialogVisible=ref(false)
- const closeAvatarDialog=(data)=> {
- dialogVisible.value = false
- }
- <script>
好啦,以上就是分享内容。如果大家有遇到问题或更好的意见,欢迎大家的留言哦! 有帮助的话,点赞点赞点赞!!!
上一篇:KubeSphere接入外部Elasticsearch实战示例
下一篇:最后一页