您好,欢迎访问一九零五行业门户网

Vue3中怎么实现选取头像并裁剪

最终效果
安装vuecropper组件yarn add vue-cropper@next
上面的安装值针对vue3的,如果时vue2或者想使用其他的方式引用,请访问它的npm官方地址:官方教程。
在组件中引用使用时也很简单,只需要引入对应的组件和它的样式文件,我这里没有在全局引用,只在我的组件文件中引入
<script>import { userinfobyrequest } from '../js/api'import { vuecropper } from 'vue-cropper'import 'vue-cropper/dist/index.css'export default { components: { vuecropper },}
然后用<vue-cropper>标签来进行使用,需要注意的是它需要有外层容器包裹,并且给外层容器设置指定的高度。
<el-dialog title="头像设置" v-model="showsetavatardialog"> <div class="cropperbox"> <vue-cropper ref="cropper" :canmovebox="false" :img="avatarbase64" :fixedbox="true" :autocrop="true" autocropwidth="200" autocropheight="200" outputtype="png"></vue-cropper> </div> <div class="optionbtn"> <el-button @click="rotateleft"><i class="fa fa-rotate-left"></i>左旋转</el-button> <el-button @click="rotateright"><i class="fa fa-rotate-right"></i>右旋转</el-button> <el-button @click="getpickavatar" type="primary"><i class="fa fa-save"></i>保存</el-button> </div></el-dialog>
我这里是将它放到一个dialog弹框中,当选择完图片后会弹出这弹框。
关于它的一些属性可以参考:官方教程中的详细描述,上面用到的属性含义:
canmovebox:截图框能否移动,默认是可以的,我设置为false,因为我想让图片移动,截图框不动。
img:图片源,可以是图片网址也可以是base64数据。
fixedbox:不允许改变截图框的大小,默认是可以的,这里我设置为了true,因为我想要一个固定长宽的正方形。
autocrop:是否默认生成截图框,这里设置为了true
autocropwidth:自动生成截图框的默认宽度
autocropheight:自动生成截图框的默认高度
outputtype:输出图片的格式,这里我设置为了png格式
获取图片内容通过下面这种方式,使用它内置的方法获取截取图片的内容
//获取base64格式的截图内容this.$refs.cropper.getcropdata(data => { // do something console.log(data) })//获取blob格式的截图内容this.$refs.cropper.getcropblob(data => { // do something console.log(data) })
更多其他的内置方法请参考官方教程中的详细描述。
自定义上传图片截图组件有了,下面需要我们选择一个图片,然后通过前端转换为base64后弹出截图的组件进行选择,这里用原生的input标签,type为file,但是原生的样式不是我们想要的,演示中我是点击一个相机的小图标后选择图片,这个实现过程如下:
首先将 中加入hidden属性,将它隐藏
然后当点击相机图标时通过js实现点击input的事件
在input标签中定义change事件,进行图片转base64的逻辑
然后将转换的数据设置到全局变量中
完整的代码实现usercenter.vue
<template> <div class="usercenter"> <input id="avatarfile" type="file" hidden @change="selectfile" /> <header> <div class="avatar"> <div class="back"> <el-tooltip content="返回"> <i @click="back" class="fa fa-arrow-left"></i> </el-tooltip> </div> <div class="topinfo"> <el-avatar :size="120" :src="avatarblob==null?(userinfo.avatar==null?defaultavatar:userinfo.avatar):avatarblob"></el-avatar> <div class="setavatar"> <el-tooltip content="修改头像"> <i @click="getfile" class="fa fa-camera"></i> </el-tooltip> </div> <div class="username">{{userinfo.nickname}}</div> </div> </div> </header> <el-row justify="center"> <el-col :lg="12" :xl="12" :md="18" :sm="20" :xs="20"> <div class="userinfobox"> <div class="headeroption"> <el-tooltip content="修改用户基本信息,涉及账号的修改请点击底栏的操作按钮"> <el-link @click="edituserinfo"><i class="fa fa-edit"></i></el-link> </el-tooltip> </div> <ul> <li> <div class="userinfotitle">用户名:</div> <div class="userinfovalue">{{userinfo.username}}</div> </li> <li> <div class="userinfotitle">邮箱:</div> <div class="userinfovalue">{{userinfo.email}}</div> </li> <li> <div class="userinfotitle">昵称:</div> <div class="userinfovalue">{{userinfo.nickname}}</div> </li> <li> <div class="userinfotitle">性别:</div> <div class="userinfovalue">{{userinfo.gender==3?'保密':(userinfo.gender==0?'男':'女')}}</div> </li> <li> <div class="userinfotitle">年龄:</div> <div class="userinfovalue">{{userinfo.age}}</div> </li> <li> <div class="userinfotitle">生日:</div> <div class="userinfovalue">{{userinfo.birthday}}</div> </li> </ul> </div> </el-col> </el-row> <div class="option"> <el-button class="optionbtn" size="large" round><i class="fa fa-user"></i>用户名修改</el-button> <el-button class="optionbtn" size="large" round><i class="fa fa-lock"></i>修改密码</el-button> <el-button class="optionbtn" size="large" round><i class="fa fa-envelope"></i>修改邮箱</el-button> <el-button class="optionbtn" size="large" round><i class="fa fa-toggle-on"></i>激活邮箱</el-button> <el-button class="optionbtn" size="large" round><i class="fa fa-power-off"></i>注销账号</el-button> </div> <el-dialog title="基本信息" v-model="showuserinfodialog"> <el-form :model="userinfoform"> <el-form-item label="昵称"> <el-input placeholder="请输入昵称" v-model="userinfoform.nickname"></el-input> </el-form-item> <el-form-item label="性别"> <el-select v-model="userinfoform.gender"> <el-option v-for="item in genders" :key="item.id" :label="item.gendername" :value="item.gendercode"></el-option> </el-select> </el-form-item> <el-form-item label="生日"> <el-date-picker v-model="userinfoform.birthday" :locale="locale" placeholder="选择出生日期" value-format="yyyy-mm-dd"></el-date-picker> </el-form-item> <div class="submitbtn" > <el-button @click="showuserinfodialog=false" type="info">取消</el-button> <el-button type="primary">确定</el-button> </div> </el-form> </el-dialog> <el-dialog title="头像设置" v-model="showsetavatardialog"> <div class="cropperbox"> <vue-cropper ref="cropper" :canmovebox="false" :img="avatarbase64" :fixedbox="true" :autocrop="true" autocropwidth="200" autocropheight="200" outputtype="png"></vue-cropper> </div> <div class="optionbtn"> <el-button @click="rotateleft"><i class="fa fa-rotate-left"></i>左旋转</el-button> <el-button @click="rotateright"><i class="fa fa-rotate-right"></i>右旋转</el-button> <el-button @click="getpickavatar" type="primary"><i class="fa fa-save"></i>保存</el-button> </div> </el-dialog> </div></template><script>import { userinfobyrequest } from '../js/api'import { vuecropper } from 'vue-cropper'import 'vue-cropper/dist/index.css'export default { components: { vuecropper }, data() { return { userinfo: {}, defaultavatar: 'https://cube.elemecdn.com/9/c2/f0ee8a3c7c9638a54940382568c9dpng.png', userinfoform: {}, genders: [ { id: 1, gendername: '男性', gendercode: 0, }, { id: 2, gendername: '女性', gendercode: 1, }, { id: 3, gendername: '保密', gendercode: 3, } ], showuserinfodialog: false, showsetavatardialog: false, avatarbase64:'', avatarblob: null } }, methods: { back() { this.$router.go(-1) }, getuserinfo() { userinfobyrequest().then(res => { this.userinfo = res.data; }) }, edituserinfo() { this.userinfoform.nickname = this.userinfo.nickname; this.userinfoform.gender = this.userinfo.gender; this.userinfoform.birthday = this.userinfo.birthday; this.showuserinfodialog = true; }, getpickavatar() { this.$refs.cropper.getcropdata(data => { this.avatarblob = data }) this.showsetavatardialog = false; }, rotateleft() { this.$refs.cropper.rotateleft(); }, rotateright() { this.$refs.cropper.rotateright(); }, getfile() { let fileele = document.getelementbyid('avatarfile') fileele.click() }, selectfile(e) { var file = e.target.files[0]; var filesize = file.size; var filename = file.name; var reader = new filereader(); reader.readasdataurl(file); reader.onload = (e) => { var imgcode = e.target.result; this.avatarbase64 = imgcode this.showsetavatardialog = true; } } }, mounted() { this.getuserinfo(); }}</script><style scoped>.usercenter { display: flex; flex-direction: column; justify-content: center;}.username { color: #fff; font-weight: bold; font-size: 19px; padding: 0 10px;}header { text-align: center; padding: 10px; background-color: #333;}.topinfo { animation: userinfocard 2s; -webkit-animation: userinfocard 2s; /* safari and chrome */}.back { text-align: left; color: #fff; position: relative; left: 10px;}.back>i { cursor: pointer;}.userinfobox { box-shadow: 2px 3px 10px #d3d7d4; margin-top: 20px; padding: 20px; background-color: #fff; font-size: 16px; text-align: center; border-radius: 4px; animation: userinfocard 3s; -webkit-animation: userinfocard 3s; /* safari and chrome */}.setavatar { position: relative; top: -20px; font-size: 14px; color: #000; margin: -10px;}.setavatar>i { cursor: pointer;}ul>li { display: flex; padding: 5px;}.userinfotitle { font-weight: bold; width: 100px; text-align: right; padding-right: 10px;}.option { width: 100%; text-align: center; position: fixed; bottom: 20px; border: 1px solid gainsboro; padding: 10px;}.optionbtn { font-weight: bold; text-align: center; margin-top: 10px;}.headeroption { text-align: right;}@keyframes userinfocard { from { opacity: 0; } to { opacity: 1; }}@-webkit-keyframes userinfocard/* safari and chrome */ { from { opacity: 0; } to { opacity: 1; }}.cropperbox { width: 100%; height: 300px;}</style>
以上就是vue3中怎么实现选取头像并裁剪的详细内容。
其它类似信息

推荐信息