欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Vue3中實現(xiàn)選取頭像并裁剪

 更新時間:2023年04月10日 09:12:15   作者:@胡海龍  
這篇文章主要詳細介紹了在vue3中如何選取頭像并裁剪,文章中有詳細的代碼示例,需要的朋友可以參考閱讀

在一個項目中,尤其是個人中心功能中,免不了要有設置頭像的功能,設置時為了最后展示的時候美觀好看,一般我們會采取提前截取用戶想要的部分,截取時支持放大,縮小,旋轉等操作,本文將描述如何在Vue3中實現(xiàn)點擊選取圖片并裁剪出想要的頭像后設置頭像。

最終效果

安裝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:圖片源,可以是圖片網(wǎng)址也可以是base64數(shù)據(jù)。
  • fixedBox:不允許改變截圖框的大小,默認是可以的,這里我設置為了true,因為我想要一個固定長寬的正方形。
  • autoCrop:是否默認生成截圖框,這里設置為了true
  • autoCropWidth:自動生成截圖框的默認寬度
  • autoCropHeight:自動生成截圖框的默認高度
  • outputType:輸出圖片的格式,這里我設置為了png格式

獲取圖片內(nèi)容

通過下面這種方式,使用它內(nèi)置的方法獲取截取圖片的內(nèi)容

//獲取base64格式的截圖內(nèi)容
this.$refs.cropper.getCropData(data => {
  // do something
  console.log(data)  
})
//獲取blob格式的截圖內(nèi)容
this.$refs.cropper.getCropBlob(data => {
  // do something
  console.log(data)  
})

更多其他的內(nèi)置方法請參考官方教程中的詳細描述。

自定義上傳圖片

截圖組件有了,下面需要我們選擇一個圖片,然后通過前端轉換為base64后彈出截圖的組件進行選擇,這里用原生的input標簽,type為file,但是原生的樣式不是我們想要的,演示中我是點擊一個相機的小圖標后選擇圖片,這個實現(xiàn)過程如下:

  1. 首先將 中加入hidden屬性,將它隱藏
  2. 然后當點擊相機圖標時通過js實現(xiàn)點擊input的事件
  3. 在input標簽中定義change事件,進行圖片轉base64的邏輯
  4. 然后將轉換的數(shù)據(jù)設置到全局變量中

完整的代碼實現(xiàn)

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" style="text-align:right;">
                    <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中實現(xiàn)選取頭像并裁剪的文章就介紹到這了,更多相關Vue3實現(xiàn)頭像并裁剪內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • vue封裝echarts組件,數(shù)據(jù)動態(tài)渲染方式

    vue封裝echarts組件,數(shù)據(jù)動態(tài)渲染方式

    這篇文章主要介紹了vue封裝echarts組件,數(shù)據(jù)動態(tài)渲染方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-12-12
  • vue設置動態(tài)請求地址的例子

    vue設置動態(tài)請求地址的例子

    今天小編就為大家分享一篇vue設置動態(tài)請求地址的例子,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-11-11
  • 從vue-router看前端路由的兩種實現(xiàn)

    從vue-router看前端路由的兩種實現(xiàn)

    本文由淺入深觀摩vue-router源碼是如何通過hash與History interface兩種方式實現(xiàn)前端路由,介紹了相關原理,并對比了兩種方式的優(yōu)缺點與注意事項。最后分析了如何實現(xiàn)可以直接從文件系統(tǒng)加載而不借助后端服務器的Vue單頁應用。
    2021-05-05
  • vue3+element-plus?Dialog對話框的使用與setup?寫法的用法

    vue3+element-plus?Dialog對話框的使用與setup?寫法的用法

    這篇文章主要介紹了vue3+element-plus?Dialog對話框的使用?與?setup?寫法的使用,本文通過兩種方式結合實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-04-04
  • 淺談Vue頁面級緩存解決方案feb-alive (下)

    淺談Vue頁面級緩存解決方案feb-alive (下)

    這篇文章主要介紹了淺談Vue頁面級緩存解決方案feb-alive(下),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-04-04
  • vue和js中實現(xiàn)模糊查詢方式

    vue和js中實現(xiàn)模糊查詢方式

    這篇文章主要介紹了vue和js中實現(xiàn)模糊查詢方式,具有很好的參考價值,希望對大家有所幫助。也希望大家多多支持腳本之家
    2022-08-08
  • 基于Vue實現(xiàn)支持按周切換的日歷

    基于Vue實現(xiàn)支持按周切換的日歷

    這篇文章主要為大家詳細介紹了基于Vue實現(xiàn)支持按周切換的日歷,根據(jù)實際開發(fā)情況按每年、每月、每周進行切換,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-08-08
  • Vue.JS入門教程之列表渲染

    Vue.JS入門教程之列表渲染

    這篇文章主要為大家詳細介紹了Vue.JS入門教程之列表渲染,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2016-12-12
  • vue使用map代替Aarry數(shù)組循環(huán)遍歷的方法

    vue使用map代替Aarry數(shù)組循環(huán)遍歷的方法

    這篇文章主要介紹了vue使用map代替Aarry數(shù)組循環(huán)遍歷的方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-04-04
  • vue-cli腳手架的安裝教程圖解

    vue-cli腳手架的安裝教程圖解

    vue-cli腳手架模板是基于node下的npm來完成安裝,這篇文章主要介紹了vue-cli腳手架的安裝教程圖解 ,需要的朋友可以參考下
    2018-09-09

最新評論