# MatchProfileSet
A personal profile setting component that provides editing functionality for user avatar, nickname and other basic information, supporting avatar upload and nickname modification.
# Import
import PressMatchProfileSet from 'press-next/press-match-profile-set/press-match-profile-set.vue';
# Usage
# Basic Usage
<template>
<PressMatchProfileSet
desc="To facilitate content display on pages such as scores, authorize us to get your account nickname"
:avatar-url="avatarUrl"
:nickname="nickname"
@avatar-click="handleAvatarClick"
@nickname-change="handleNicknameChange"
@account-click="handleAccountClick"
/>
</template>
<script setup>
import { ref } from 'vue';
const avatarUrl = ref('https://example.com/avatar.jpg');
const nickname = ref('User Nickname');
const handleAvatarClick = () => {
console.log('Avatar clicked');
};
const handleNicknameChange = (value) => {
console.log('Nickname changed:', value);
nickname.value = value;
};
const handleAccountClick = () => {
console.log('Switch account button clicked');
};
</script>
# Avatar Upload
The component supports avatar click upload functionality:
<template>
<PressMatchProfileSet
:avatar-url="avatarUrl"
:nickname="nickname"
@avatar-click="handleAvatarUpload"
/>
</template>
<script setup>
import { ref } from 'vue';
const avatarUrl = ref('');
const nickname = ref('Enter nickname');
const handleAvatarUpload = () => {
// Call image picker
uni.chooseImage({
count: 1,
sizeType: ['compressed'],
sourceType: ['album', 'camera'],
success: (res) => {
avatarUrl.value = res.tempFilePaths[0];
// Upload to server
uploadAvatar(res.tempFilePaths[0]);
}
});
};
const uploadAvatar = (filePath) => {
uni.uploadFile({
url: 'https://api.example.com/upload',
filePath,
name: 'avatar',
success: (uploadRes) => {
const data = JSON.parse(uploadRes.data);
avatarUrl.value = data.url;
}
});
};
</script>
# Nickname Editing
Supports real-time nickname editing and validation:
<template>
<PressMatchProfileSet
:avatar-url="avatarUrl"
:nickname="nickname"
nickname-placeholder="Please enter your nickname"
@nickname-change="handleNicknameChange"
@nickname-blur="handleNicknameBlur"
/>
</template>
<script setup>
import { ref } from 'vue';
const avatarUrl = ref('https://example.com/avatar.jpg');
const nickname = ref('');
const handleNicknameChange = (value) => {
nickname.value = value;
};
const handleNicknameBlur = (value) => {
// Nickname length validation
if (value.length > 20) {
uni.showToast({
title: 'Nickname cannot exceed 20 characters',
icon: 'none'
});
return;
}
// Sensitive word filtering
if (containsSensitiveWords(value)) {
uni.showToast({
title: 'Nickname contains sensitive words',
icon: 'none'
});
return;
}
};
const containsSensitiveWords = (text) => {
const sensitiveWords = ['badword1', 'badword2'];
return sensitiveWords.some(word => text.includes(word));
};
</script>
# Custom Footer Button
<template>
<PressMatchProfileSet
:avatar-url="avatarUrl"
:nickname="nickname"
foot-button-text="Logout"
@account-click="handleLogout"
>
<template #confirm-btn>
<PressButton
type="primary"
block
@click="handleCustomAction"
>
Custom Button
</PressButton>
</template>
</PressMatchProfileSet>
</template>
<script setup>
import { ref } from 'vue';
const avatarUrl = ref('https://example.com/avatar.jpg');
const nickname = ref('User Nickname');
const handleLogout = () => {
console.log('Logout');
};
const handleCustomAction = () => {
console.log('Custom action');
};
</script>
# Complete Example
<template>
<div class="profile-page">
<PressMatchProfileSet
desc="To facilitate content display on pages such as scores, authorize us to get your account nickname"
:avatar-url="avatarUrl"
:nickname="nickname"
:default-avatar-url="defaultAvatar"
nickname-placeholder="Please enter nickname"
foot-button-text="Switch QQ Account"
custom-class="custom-profile"
@avatar-click="handleAvatarClick"
@nickname-change="handleNicknameChange"
@nickname-blur="handleNicknameBlur"
@nickname-auth="handleNicknameAuth"
@account-click="handleAccountClick"
/>
</div>
</template>
<script setup>
import { ref } from 'vue';
const avatarUrl = ref('');
const nickname = ref('');
const defaultAvatar = 'https://example.com/default-avatar.png';
const handleAvatarClick = () => {
uni.showActionSheet({
itemList: ['Take Photo', 'Choose from Album'],
success: (res) => {
const sourceType = res.tapIndex === 0 ? ['camera'] : ['album'];
uni.chooseImage({
count: 1,
sizeType: ['compressed'],
sourceType,
success: (chooseRes) => {
uploadAvatar(chooseRes.tempFilePaths[0]);
}
});
}
});
};
const handleNicknameChange = (value) => {
nickname.value = value;
};
const handleNicknameBlur = (value) => {
if (!value.trim()) {
uni.showToast({
title: 'Please enter nickname',
icon: 'none'
});
return;
}
if (value.length > 20) {
uni.showToast({
title: 'Nickname cannot exceed 20 characters',
icon: 'none'
});
return;
}
};
const handleNicknameAuth = () => {
console.log('Trigger WeChat nickname authorization');
};
const handleAccountClick = () => {
uni.showModal({
title: 'Confirm',
content: 'Are you sure you want to switch account?',
success: (res) => {
if (res.confirm) {
// Execute account switching logic
console.log('Switch account');
}
}
});
};
const uploadAvatar = (filePath) => {
uni.showLoading({ title: 'Uploading...' });
uni.uploadFile({
url: 'https://api.example.com/upload/avatar',
filePath,
name: 'avatar',
success: (res) => {
const data = JSON.parse(res.data);
avatarUrl.value = data.url;
uni.hideLoading();
},
fail: () => {
uni.hideLoading();
uni.showToast({
title: 'Upload failed',
icon: 'none'
});
}
});
};
</script>
# API
# Props
| Attribute | Description | Type | Default |
|---|---|---|---|
| foot-button-text | Footer button text | string | '切换QQ账号' |
| custom-class | Custom style class name | string | '' |
| authorization-class | Authorization item custom style class name | string | '' |
| desc | Description text | string | '' |
| avatar-url | Avatar URL | string | '' |
| nickname | Nickname | string | '' |
| default-avatar-url | Default avatar URL | string | '' |
| nickname-placeholder | Nickname input placeholder | string | '' |
# Events
| Event | Description | Parameters |
|---|---|---|
| account-click | Triggered when footer button is clicked | - |
| avatar-click | Triggered when avatar is clicked | - |
| nickname-change | Triggered when nickname input changes | value: string |
| nickname-blur | Triggered when nickname input loses focus | value: string |
| nickname-auth | Triggered when clicking the arrow on the right side of nickname, used to trigger WeChat nickname authorization | - |
# Slots
| Name | Description |
|---|---|
| confirm-btn | Custom footer button |
# Style Variables
The component provides the following CSS variables, which can be used to customize styles.
| Name | Default Value | Description |
|---|---|---|
| --pmps-profile-foot-mt | $spacing-xl | Footer button top margin |
| --pmps-profile-padding-lr | $spacing-lg | Component left and right padding |
| --pmps-profile-foot-padding-lr | $spacing-md | Footer button left and right padding |
| --pmps-foot-height | 1.08rem | Footer button height |
| --pmps-profile-bg-color | $color-surface-default | Background color |
# Custom Style Example
<template>
<PressMatchProfileSet
:avatar-url="avatarUrl"
:nickname="nickname"
class="custom-profile-set"
/>
</template>
<style>
.custom-profile-set {
--pmps-profile-bg-color: #f8f9fa;
--pmps-profile-padding-lr: 20px;
--pmps-profile-foot-mt: 30px;
--pmps-foot-height: 44px;
}
</style>
# Notes
- This component is mainly used for personal profile setting pages, providing avatar and nickname editing functionality
- Avatar display priority:
avatar-url>default-avatar-url - The component internally uses the
PressMatchAuthorizationItemcomponent to render authorization items - The default footer button text is "切换QQ账号" (Switch QQ Account), which can be customized via
foot-button-text - Supports fully customizing the footer button through slots
# FAQ
# How to get WeChat Mini Program avatar?
const handleAvatarClick = () => {
wx.chooseMedia({
count: 1,
mediaType: ['image'],
sourceType: ['album', 'camera'],
success: (res) => {
avatarUrl.value = res.tempFiles[0].tempFilePath;
}
});
};
# How to validate nickname format?
const handleNicknameBlur = (value) => {
if (value.length < 2) {
wx.showToast({ title: 'Nickname must be at least 2 characters', icon: 'none' });
return;
}
if (value.length > 20) {
wx.showToast({ title: 'Nickname cannot exceed 20 characters', icon: 'none' });
return;
}
// Other validation logic...
};
# How to upload avatar to server?
const uploadAvatar = (tempFilePath) => {
wx.uploadFile({
url: 'https://your-api.com/upload',
filePath: tempFilePath,
name: 'avatar',
success: (res) => {
const data = JSON.parse(res.data);
avatarUrl.value = data.url;
}
});
};