亚洲国产日韩欧美一区二区三区,精品亚洲国产成人av在线,国产99视频精品免视看7,99国产精品久久久久久久成人热,欧美日韩亚洲国产综合乱

目錄
最終效果
安裝VueCropper組件
在組件中引用
獲取圖片內(nèi)容
自定義上傳圖片
完整的代碼實(shí)現(xiàn)
首頁(yè) web前端 Vue.js Vue3中怎么實(shí)現(xiàn)選取頭像并裁剪

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

May 29, 2023 am 10:22 AM
vue3

最終效果

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

安裝VueCropper組件

yarn add vue-cropper@next

上面的安裝值針對(duì)Vue3的,如果時(shí)Vue2或者想使用其他的方式引用,請(qǐng)?jiān)L問(wèn)它的npm官方地址:官方教程。

在組件中引用

使用時(shí)也很簡(jiǎn)單,只需要引入對(duì)應(yīng)的組件和它的樣式文件,我這里沒(méi)有在全局引用,只在我的組件文件中引入

<script>
import { userInfoByRequest } from &#39;../js/api&#39;
import { VueCropper } from &#39;vue-cropper&#39;
import &#39;vue-cropper/dist/index.css&#39;
export default {
    components: {
        VueCropper
    },
}

然后用<vue-cropper>標(biāo)簽來(lái)進(jìn)行使用,需要注意的是它需要有外層容器包裹,并且給外層容器設(shè)置指定的高度。

<el-dialog title="頭像設(shè)置" 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>左旋轉(zhuǎn)</el-button>
                <el-button @click="rotateRight"><i class="fa fa-rotate-right"></i>右旋轉(zhuǎn)</el-button>
                <el-button @click="getPickAvatar" type="primary"><i class="fa fa-save"></i>保存</el-button>
            </div>
</el-dialog>

我這里是將它放到一個(gè)Dialog彈框中,當(dāng)選擇完圖片后會(huì)彈出這彈框。
關(guān)于它的一些屬性可以參考:官方教程中的詳細(xì)描述,上面用到的屬性含義:

  • canMoveBox:截圖框能否移動(dòng),默認(rèn)是可以的,我設(shè)置為false,因?yàn)槲蚁胱寛D片移動(dòng),截圖框不動(dòng)。

  • img:圖片源,可以是圖片網(wǎng)址也可以是base64數(shù)據(jù)。

  • fixedBox:不允許改變截圖框的大小,默認(rèn)是可以的,這里我設(shè)置為了true,因?yàn)槲蚁胍粋€(gè)固定長(zhǎng)寬的正方形。

  • autoCrop:是否默認(rèn)生成截圖框,這里設(shè)置為了true

  • autoCropWidth:自動(dòng)生成截圖框的默認(rèn)寬度

  • autoCropHeight:自動(dòng)生成截圖框的默認(rèn)高度

  • outputType:輸出圖片的格式,這里我設(shè)置為了png格式

獲取圖片內(nèi)容

通過(guò)下面這種方式,使用它內(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)置方法請(qǐng)參考官方教程中的詳細(xì)描述。

自定義上傳圖片

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

  1. 首先將 中加入hidden屬性,將它隱藏

  2. 然后當(dāng)點(diǎn)擊相機(jī)圖標(biāo)時(shí)通過(guò)js實(shí)現(xiàn)點(diǎn)擊input的事件

  3. 在input標(biāo)簽中定義change事件,進(jìn)行圖片轉(zhuǎn)base64的邏輯

  4. 然后將轉(zhuǎn)換的數(shù)據(jù)設(shè)置到全局變量中

完整的代碼實(shí)現(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="修改用戶基本信息,涉及賬號(hào)的修改請(qǐng)點(diǎn)擊底欄的操作按鈕">
                            <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?&#39;保密&#39;:(userInfo.gender==0?&#39;男&#39;:&#39;女&#39;)}}</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>注銷賬號(hào)</el-button>
        </div>
        <el-dialog title="基本信息" v-model="showUserInfoDialog">
            <el-form :model="userInfoForm">
                <el-form-item label="昵稱">
                    <el-input placeholder="請(qǐng)輸入昵稱" 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="頭像設(shè)置" 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>左旋轉(zhuǎn)</el-button>
                <el-button @click="rotateRight"><i class="fa fa-rotate-right"></i>右旋轉(zhuǎn)</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 &#39;../js/api&#39;
import { VueCropper } from &#39;vue-cropper&#39;
import &#39;vue-cropper/dist/index.css&#39;
export default {
    components: {
        VueCropper
    },
    data() {
        return {
            userInfo: {},
            defaultAvatar: &#39;https://cube.elemecdn.com/9/c2/f0ee8a3c7c9638a54940382568c9dpng.png&#39;,
            userInfoForm: {},
            genders: [
                {
                    id: 1,
                    genderName: &#39;男性&#39;,
                    genderCode: 0,
                },
                {
                    id: 2,
                    genderName: &#39;女性&#39;,
                    genderCode: 1,
                },
                {
                    id: 3,
                    genderName: &#39;保密&#39;,
                    genderCode: 3,
                }
            ],
            showUserInfoDialog: false,
            showSetAvatarDialog: false,
            avatarBase64:&#39;&#39;,
            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(&#39;avatarFile&#39;)
            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中怎么實(shí)現(xiàn)選取頭像并裁剪的詳細(xì)內(nèi)容。更多信息請(qǐng)關(guān)注PHP中文網(wǎng)其他相關(guān)文章!

本站聲明
本文內(nèi)容由網(wǎng)友自發(fā)貢獻(xiàn),版權(quán)歸原作者所有,本站不承擔(dān)相應(yīng)法律責(zé)任。如您發(fā)現(xiàn)有涉嫌抄襲侵權(quán)的內(nèi)容,請(qǐng)聯(lián)系admin@php.cn

熱AI工具

Undress AI Tool

Undress AI Tool

免費(fèi)脫衣服圖片

Undresser.AI Undress

Undresser.AI Undress

人工智能驅(qū)動(dòng)的應(yīng)用程序,用于創(chuàng)建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用于從照片中去除衣服的在線人工智能工具。

Clothoff.io

Clothoff.io

AI脫衣機(jī)

Video Face Swap

Video Face Swap

使用我們完全免費(fèi)的人工智能換臉工具輕松在任何視頻中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費(fèi)的代碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

功能強(qiáng)大的PHP集成開(kāi)發(fā)環(huán)境

Dreamweaver CS6

Dreamweaver CS6

視覺(jué)化網(wǎng)頁(yè)開(kāi)發(fā)工具

SublimeText3 Mac版

SublimeText3 Mac版

神級(jí)代碼編輯軟件(SublimeText3)

Vue3如何實(shí)現(xiàn)刷新頁(yè)面局部?jī)?nèi)容 Vue3如何實(shí)現(xiàn)刷新頁(yè)面局部?jī)?nèi)容 May 26, 2023 pm 05:31 PM

想要實(shí)現(xiàn)頁(yè)面的局部刷新,我們只需要實(shí)現(xiàn)局部組件(dom)的重新渲染。在Vue中,想要實(shí)現(xiàn)這一效果最簡(jiǎn)便的方式方法就是使用v-if指令。在Vue2中我們除了使用v-if指令讓局部dom的重新渲染,也可以新建一個(gè)空白組件,需要刷新局部頁(yè)面時(shí)跳轉(zhuǎn)至這個(gè)空白組件頁(yè)面,然后在空白組件內(nèi)的beforeRouteEnter守衛(wèi)中又跳轉(zhuǎn)回原來(lái)的頁(yè)面。如下圖所示,如何在Vue3.X中實(shí)現(xiàn)點(diǎn)擊刷新按鈕實(shí)現(xiàn)紅框范圍內(nèi)的dom重新加載,并展示對(duì)應(yīng)的加載狀態(tài)。由于Vue3.X中scriptsetup語(yǔ)法中組件內(nèi)守衛(wèi)只有o

Vue3怎么解析markdown并實(shí)現(xiàn)代碼高亮顯示 Vue3怎么解析markdown并實(shí)現(xiàn)代碼高亮顯示 May 20, 2023 pm 04:16 PM

Vue實(shí)現(xiàn)博客前端,需要實(shí)現(xiàn)markdown的解析,如果有代碼則需要實(shí)現(xiàn)代碼的高亮。Vue的markdown解析庫(kù)有很多,如markdown-it、vue-markdown-loader、marked、vue-markdown等。這些庫(kù)都大同小異。這里選用的是marked,代碼高亮的庫(kù)選用的是highlight.js。具體實(shí)現(xiàn)步驟如下:一、安裝依賴庫(kù)在vue項(xiàng)目下打開(kāi)命令窗口,并輸入以下命令npminstallmarked-save//marked用于將markdown轉(zhuǎn)換成htmlnpmins

vue3+vite:src使用require動(dòng)態(tài)導(dǎo)入圖片報(bào)錯(cuò)怎么解決 vue3+vite:src使用require動(dòng)態(tài)導(dǎo)入圖片報(bào)錯(cuò)怎么解決 May 21, 2023 pm 03:16 PM

vue3+vite:src使用require動(dòng)態(tài)導(dǎo)入圖片報(bào)錯(cuò)和解決方法vue3+vite動(dòng)態(tài)的導(dǎo)入多張圖片vue3如果使用的是typescript開(kāi)發(fā),就會(huì)出現(xiàn)require引入圖片報(bào)錯(cuò),requireisnotdefined不能像使用vue2這樣imgUrl:require(’…/assets/test.png’)導(dǎo)入,是因?yàn)閠ypescript不支持require所以用import導(dǎo)入,下面介紹如何解決:使用awaitimport

vue3項(xiàng)目中怎么使用tinymce vue3項(xiàng)目中怎么使用tinymce May 19, 2023 pm 08:40 PM

tinymce是一個(gè)功能齊全的富文本編輯器插件,但在vue中引入tinymce并不像別的Vue富文本插件一樣那么順利,tinymce本身并不適配Vue,還需要引入@tinymce/tinymce-vue,并且它是國(guó)外的富文本插件,沒(méi)有通過(guò)中文版本,需要在其官網(wǎng)下載翻譯包(可能需要翻墻)。1、安裝相關(guān)依賴npminstalltinymce-Snpminstall@tinymce/tinymce-vue-S2、下載中文包3.引入皮膚和漢化包在項(xiàng)目public文件夾下新建tinymce文件夾,將下載的

Vue3中怎么實(shí)現(xiàn)選取頭像并裁剪 Vue3中怎么實(shí)現(xiàn)選取頭像并裁剪 May 29, 2023 am 10:22 AM

最終效果安裝VueCropper組件yarnaddvue-cropper@next上面的安裝值針對(duì)Vue3的,如果時(shí)Vue2或者想使用其他的方式引用,請(qǐng)?jiān)L問(wèn)它的npm官方地址:官方教程。在組件中引用使用時(shí)也很簡(jiǎn)單,只需要引入對(duì)應(yīng)的組件和它的樣式文件,我這里沒(méi)有在全局引用,只在我的組件文件中引入import{userInfoByRequest}from'../js/api'import{VueCropper}from'vue-cropper&

怎么使用vue3+ts+axios+pinia實(shí)現(xiàn)無(wú)感刷新 怎么使用vue3+ts+axios+pinia實(shí)現(xiàn)無(wú)感刷新 May 25, 2023 pm 03:37 PM

vue3+ts+axios+pinia實(shí)現(xiàn)無(wú)感刷新1.先在項(xiàng)目中下載aiXos和pinianpmipinia--savenpminstallaxios--save2.封裝axios請(qǐng)求-----下載js-cookienpmiJS-cookie-s//引入aixosimporttype{AxiosRequestConfig,AxiosResponse}from"axios";importaxiosfrom'axios';import{ElMess

vue3項(xiàng)目打包發(fā)布到服務(wù)器后訪問(wèn)頁(yè)面顯示空白怎么解決 vue3項(xiàng)目打包發(fā)布到服務(wù)器后訪問(wèn)頁(yè)面顯示空白怎么解決 May 17, 2023 am 08:19 AM

vue3項(xiàng)目打包發(fā)布到服務(wù)器后訪問(wèn)頁(yè)面顯示空白1、處理vue.config.js文件中的publicPath處理如下:const{defineConfig}=require('@vue/cli-service')module.exports=defineConfig({publicPath:process.env.NODE_ENV==='production'?'./':'/&

Vue3復(fù)用組件怎么使用 Vue3復(fù)用組件怎么使用 May 20, 2023 pm 07:25 PM

前言無(wú)論是vue還是react,當(dāng)遇到多處重復(fù)代碼的時(shí)候,我們都會(huì)想著如何復(fù)用這些代碼,而不是一個(gè)文件里充斥著一堆冗余代碼。實(shí)際上,vue和react都可以通過(guò)抽組件的方式來(lái)達(dá)到復(fù)用,但如果遇到一些很小的代碼片段,你又不想抽到另外一個(gè)文件的情況下,相比而言,react可以在相同文件里面聲明對(duì)應(yīng)的小組件,或者通過(guò)renderfunction來(lái)實(shí)現(xiàn),如:constDemo:FC=({msg})=>{returndemomsgis{msg}}constApp:FC=()=>{return(

See all articles