242 lines
17 KiB
Vue
242 lines
17 KiB
Vue
|
<template>
|
|||
|
<view class="u-avatar" :style="[wrapStyle]" @tap="click">
|
|||
|
<image
|
|||
|
@error="loadError"
|
|||
|
:style="[imgStyle]"
|
|||
|
class="u-avatar__img"
|
|||
|
v-if="!uText && avatar"
|
|||
|
:src="avatar"
|
|||
|
:mode="mode"
|
|||
|
></image>
|
|||
|
<text class="u-line-1" v-else-if="uText" :style="{
|
|||
|
fontSize: '38rpx'
|
|||
|
}">{{uText}}</text>
|
|||
|
<slot v-else></slot>
|
|||
|
<view class="u-avatar__sex" v-if="showSex" :class="['u-avatar__sex--' + sexIcon]" :style="[uSexStyle]">
|
|||
|
<u-icon :name="sexIcon" size="20"></u-icon>
|
|||
|
</view>
|
|||
|
<view class="u-avatar__level" v-if="showLevel" :style="[uLevelStyle]">
|
|||
|
<u-icon :name="levelIcon" size="20"></u-icon>
|
|||
|
</view>
|
|||
|
</view>
|
|||
|
</template>
|
|||
|
|
|||
|
<script>
|
|||
|
let base64Avatar = "data:image/png;base64,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
|
|||
|
/**
|
|||
|
* avatar 头像
|
|||
|
* @description 本组件一般用于展示头像的地方,如个人中心,或者评论列表页的用户头像展示等场所。
|
|||
|
* @tutorial https://www.uviewui.com/components/avatar.html
|
|||
|
* @property {String} bg-color 背景颜色,一般显示文字时用(默认#ffffff)
|
|||
|
* @property {String} src 头像路径,如加载失败,将会显示默认头像
|
|||
|
* @property {String Number} size 头像尺寸,可以为指定字符串(large, default, mini),或者数值,单位rpx(默认default)
|
|||
|
* @property {String} mode 显示类型,见上方说明(默认circle)
|
|||
|
* @property {String} sex-icon 性别图标,man-男,woman-女(默认man)
|
|||
|
* @property {String} level-icon 等级图标(默认level)
|
|||
|
* @property {String} sex-bg-color 性别图标背景颜色
|
|||
|
* @property {String} level-bg-color 等级图标背景颜色
|
|||
|
* @property {String} show-sex 是否显示性别图标(默认false)
|
|||
|
* @property {String} show-level 是否显示等级图标(默认false)
|
|||
|
* @property {String} img-mode 头像图片的裁剪类型,与uni的image组件的mode参数一致,如效果达不到需求,可尝试传widthFix值(默认aspectFill)
|
|||
|
* @property {String} index 用户传递的标识符值,如果是列表循环,可穿v-for的index值
|
|||
|
* @event {Function} click 头像被点击
|
|||
|
* @example <u-avatar :src="src"></u-avatar>
|
|||
|
*/
|
|||
|
export default {
|
|||
|
name: 'u-avatar',
|
|||
|
props: {
|
|||
|
// 背景颜色
|
|||
|
bgColor: {
|
|||
|
type: String,
|
|||
|
default: 'transparent'
|
|||
|
},
|
|||
|
// 头像路径
|
|||
|
src: {
|
|||
|
type: String,
|
|||
|
default: ''
|
|||
|
},
|
|||
|
// 尺寸,large-大,default-中等,mini-小,如果为数值,则单位为rpx
|
|||
|
// 宽度等于高度
|
|||
|
size: {
|
|||
|
type: [String, Number],
|
|||
|
default: 'default'
|
|||
|
},
|
|||
|
// 头像模型,square-带圆角方形,circle-圆形
|
|||
|
mode: {
|
|||
|
type: String,
|
|||
|
default: 'circle'
|
|||
|
},
|
|||
|
// 文字内容
|
|||
|
text: {
|
|||
|
type: String,
|
|||
|
default: ''
|
|||
|
},
|
|||
|
// 图片的裁剪模型
|
|||
|
imgMode: {
|
|||
|
type: String,
|
|||
|
default: 'aspectFill'
|
|||
|
},
|
|||
|
// 标识符
|
|||
|
index: {
|
|||
|
type: [String, Number],
|
|||
|
default: ''
|
|||
|
},
|
|||
|
// 右上角性别角标,man-男,woman-女
|
|||
|
sexIcon: {
|
|||
|
type: String,
|
|||
|
default: 'man'
|
|||
|
},
|
|||
|
// 右下角的等级图标
|
|||
|
levelIcon: {
|
|||
|
type: String,
|
|||
|
default: 'level'
|
|||
|
},
|
|||
|
// 右下角等级图标背景颜色
|
|||
|
levelBgColor: {
|
|||
|
type: String,
|
|||
|
default: ''
|
|||
|
},
|
|||
|
// 右上角性别图标的背景颜色
|
|||
|
sexBgColor: {
|
|||
|
type: String,
|
|||
|
default: ''
|
|||
|
},
|
|||
|
// 是否显示性别图标
|
|||
|
showSex: {
|
|||
|
type: Boolean,
|
|||
|
default: false
|
|||
|
},
|
|||
|
// 是否显示等级图标
|
|||
|
showLevel: {
|
|||
|
type: Boolean,
|
|||
|
default: false
|
|||
|
}
|
|||
|
},
|
|||
|
data() {
|
|||
|
return {
|
|||
|
error: false,
|
|||
|
// 头像的地址,因为如果加载错误,需要赋值为默认图片,props值无法修改,所以需要一个中间值
|
|||
|
avatar: this.src ? this.src : base64Avatar,
|
|||
|
}
|
|||
|
},
|
|||
|
watch: {
|
|||
|
src(n) {
|
|||
|
// 用户可能会在头像加载失败时,再次修改头像值,所以需要重新赋值
|
|||
|
if(!n) {
|
|||
|
// 如果传入null或者'',或者undefined,显示默认头像
|
|||
|
this.error = true;
|
|||
|
} else {
|
|||
|
this.avatar = n;
|
|||
|
this.error = false;
|
|||
|
}
|
|||
|
}
|
|||
|
},
|
|||
|
computed: {
|
|||
|
wrapStyle() {
|
|||
|
let style = {};
|
|||
|
style.height = this.size == 'large' ? '120rpx' : this.size == 'default' ?
|
|||
|
'90rpx' : this.size == 'mini' ? '70rpx' : this.size + 'rpx';
|
|||
|
style.width = style.height;
|
|||
|
style.flex = `0 0 ${style.height}`;
|
|||
|
style.backgroundColor = this.bgColor;
|
|||
|
style.borderRadius = this.mode == 'circle' ? '500px' : '5px';
|
|||
|
if(this.text) style.padding = `0 6rpx`;
|
|||
|
return style;
|
|||
|
},
|
|||
|
imgStyle() {
|
|||
|
let style = {};
|
|||
|
style.borderRadius = this.mode == 'circle' ? '500px' : '5px';
|
|||
|
return style;
|
|||
|
},
|
|||
|
// 取字符串的第一个字符
|
|||
|
uText() {
|
|||
|
return String(this.text)[0];
|
|||
|
},
|
|||
|
// 性别图标的自定义样式
|
|||
|
uSexStyle() {
|
|||
|
let style = {};
|
|||
|
if(this.sexBgColor) style.backgroundColor = this.sexBgColor;
|
|||
|
return style;
|
|||
|
},
|
|||
|
// 等级图标的自定义样式
|
|||
|
uLevelStyle() {
|
|||
|
let style = {};
|
|||
|
if(this.levelBgColor) style.backgroundColor = this.levelBgColor;
|
|||
|
return style;
|
|||
|
}
|
|||
|
},
|
|||
|
methods: {
|
|||
|
// 图片加载错误时,显示默认头像
|
|||
|
loadError() {
|
|||
|
this.error = true;
|
|||
|
this.avatar = base64Avatar;
|
|||
|
},
|
|||
|
click() {
|
|||
|
this.$emit('click', this.index);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
</script>
|
|||
|
|
|||
|
<style lang="scss" scoped>
|
|||
|
@import "../../libs/css/style.components.scss";
|
|||
|
|
|||
|
.u-avatar {
|
|||
|
display: inline-flex;
|
|||
|
align-items: center;
|
|||
|
justify-content: center;
|
|||
|
font-size: 28rpx;
|
|||
|
color: $u-content-color;
|
|||
|
border-radius: 10px;
|
|||
|
position: relative;
|
|||
|
|
|||
|
&__img {
|
|||
|
width: 100%;
|
|||
|
height: 100%;
|
|||
|
}
|
|||
|
|
|||
|
&__sex {
|
|||
|
position: absolute;
|
|||
|
width: 32rpx;
|
|||
|
color: #ffffff;
|
|||
|
height: 32rpx;
|
|||
|
display: flex;
|
|||
|
justify-content: center;
|
|||
|
align-items: center;
|
|||
|
border-radius: 100rpx;
|
|||
|
top: 5%;
|
|||
|
z-index: 1;
|
|||
|
right: -7%;
|
|||
|
border: 1px #ffffff solid;
|
|||
|
|
|||
|
&--man {
|
|||
|
background-color: $u-type-primary;
|
|||
|
}
|
|||
|
|
|||
|
&--woman {
|
|||
|
background-color: $u-type-error;
|
|||
|
}
|
|||
|
|
|||
|
&--none {
|
|||
|
background-color: $u-type-warning;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
&__level {
|
|||
|
position: absolute;
|
|||
|
width: 32rpx;
|
|||
|
color: #ffffff;
|
|||
|
height: 32rpx;
|
|||
|
display: flex;
|
|||
|
justify-content: center;
|
|||
|
align-items: center;
|
|||
|
border-radius: 100rpx;
|
|||
|
bottom: 5%;
|
|||
|
z-index: 1;
|
|||
|
right: -7%;
|
|||
|
border: 1px #ffffff solid;
|
|||
|
background-color: $u-type-warning;
|
|||
|
}
|
|||
|
}
|
|||
|
</style>
|