|
|
<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>
|