# MatchAuthorizationItem 授权信息项组件

授权信息项组件,用于展示和编辑用户的头像和昵称信息,通常作为授权弹窗的内容部分使用。

# 引入

import PressMatchAuthorizationItem from 'press-next/press-next/press-match-authorization-item/press-match-authorization-item.vue'

# 代码演示

# 基础用法

<template>
  <PressMatchAuthorizationItem
    desc="为方便成绩等页面内容展示,授权我们获取您的账号昵称"
    @avatar-click="handleAvatarClick"
    @nickname-change="handleNicknameChange"
  />
</template>

<script setup>
const handleAvatarClick = () => {
  console.log('点击头像')
}

const handleNicknameChange = (value) => {
  console.log('昵称变化:', value)
}
</script>

# 自定义头像和昵称

<template>
  <PressMatchAuthorizationItem
    desc="请完善您的个人信息"
    :avatar-url="avatarUrl"
    :nickname="nickname"
    nickname-placeholder="请输入您的昵称"
    @avatar-click="handleAvatarClick"
    @avatar-change="handleAvatarChange"
    @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 handleAvatarClick = () => {
  // 打开头像选择器
  console.log('选择头像')
}

const handleAvatarChange = (avatarUrl) => {
  // 微信小程序头像选择回调
  console.log('头像变化:', avatarUrl)
}

const handleNicknameChange = (value) => {
  nickname.value = value
}

const handleNicknameBlur = (value) => {
  console.log('昵称输入完成:', value)
}

const handleNicknameAuth = () => {
  // 拉起微信昵称授权
  console.log('拉起微信昵称授权')
}
</script>

# 完整功能示例

<template>
  <div class="authorization-container">
    <PressMatchAuthorizationItem
      desc="为了更好的用户体验,请授权获取以下信息"
      :avatar-url="userInfo.avatar"
      :nickname="userInfo.nickname"
      :default-avatar-url="defaultAvatar"
      nickname-placeholder="请输入您的昵称"
      custom-class="custom-authorization"
      @avatar-click="handleAvatarClick"
      @nickname-change="handleNicknameChange"
      @nickname-blur="handleNicknameBlur"
      @nickname-auth="handleNicknameAuth"
    />
  </div>
</template>

<script setup>
import { ref, reactive } from 'vue'

const userInfo = reactive({
  avatar: '',
  nickname: ''
})

const defaultAvatar = 'https://image-1251917893.file.myqcloud.com/general-match-components/img/common/avatar/default-avatar.png'

const handleAvatarClick = () => {
  // 微信小程序会自动触发 avatar-change 事件
  // 非微信小程序需要自行实现头像选择逻辑
  // #ifndef MP-WEIXIN
  wx.chooseMedia({
    count: 1,
    mediaType: ['image'],
    sourceType: ['album', 'camera'],
    success: (res) => {
      userInfo.avatar = res.tempFiles[0].tempFilePath
      // 上传到服务器
      uploadAvatar(userInfo.avatar)
    }
  })
  // #endif
}

// 微信小程序头像选择成功回调
const handleAvatarChange = (avatarUrl) => {
  userInfo.avatar = avatarUrl
  // 上传到服务器
  uploadAvatar(avatarUrl)
}

const handleNicknameChange = (value) => {
  userInfo.nickname = value
}

const handleNicknameBlur = (value) => {
  // 验证昵称格式
  if (value.length < 2) {
    wx.showToast({ title: '昵称至少2个字符', icon: 'none' })
    return
  }
  if (value.length > 20) {
    wx.showToast({ title: '昵称不能超过20个字符', icon: 'none' })
    return
  }
  userInfo.nickname = value
}

const handleNicknameAuth = () => {
  // 拉起微信小程序昵称授权
  wx.getUserProfile({
    desc: '用于完善会员资料',
    success: (res) => {
      userInfo.nickname = res.userInfo.nickName
      wx.showToast({ title: '授权成功', icon: 'success' })
    },
    fail: () => {
      wx.showToast({ title: '授权失败', icon: 'none' })
    }
  })
}

const uploadAvatar = (tempFilePath) => {
  wx.uploadFile({
    url: 'https://your-api.com/upload',
    filePath: tempFilePath,
    name: 'avatar',
    success: (res) => {
      const data = JSON.parse(res.data)
      userInfo.avatar = data.url
    }
  })
}
</script>

# 无描述文本

<template>
  <PressMatchAuthorizationItem
    :avatar-url="avatarUrl"
    :nickname="nickname"
    @avatar-click="handleAvatarClick"
    @nickname-change="handleNicknameChange"
  />
</template>

# 自定义描述内容

<template>
  <PressMatchAuthorizationItem
    @avatar-click="handleAvatarClick"
    @nickname-change="handleNicknameChange"
  >
    <template #description>
      <div class="custom-desc">
        <p>为了提供更好的服务,请授权获取:</p>
        <ul>
          <li>头像信息:用于个人资料展示</li>
          <li>昵称信息:用于排行榜和社交功能</li>
        </ul>
      </div>
    </template>
  </PressMatchAuthorizationItem>
</template>

# 在弹窗中使用

<template>
  <PressPopupPlus :show="showAuth" @close="closeAuth">
    <div class="auth-popup">
      <div class="auth-header">
        <h3>获取授权信息</h3>
      </div>
      
      <PressMatchAuthorizationItem
        desc="为方便成绩等页面内容展示,授权我们获取您的账号昵称"
        :avatar-url="avatarUrl"
        :nickname="nickname"
        @avatar-click="handleAvatarClick"
        @nickname-change="handleNicknameChange"
      />
      
      <div class="auth-footer">
        <PressButton @click="closeAuth">取消</PressButton>
        <PressButton type="primary" @click="confirmAuth">确认</PressButton>
      </div>
    </div>
  </PressPopupPlus>
</template>

# API

# Props

参数 说明 类型 默认值
desc 描述文本 string '为方便成绩等页面内容展示,授权我们获取您的账号昵称'
avatar-url 头像URL string ''
nickname 昵称 string ''
default-avatar-url 默认头像URL string 'https://image-1251917893.file.myqcloud.com/general-match-components/img/common/avatar/default-avatar.png'
nickname-placeholder 昵称输入框占位符 string '请输入昵称'
custom-class 自定义样式类名 string ''

# Events

事件名 说明 回调参数 平台
avatar-click 点击头像时触发 - 全平台
avatar-change 微信小程序头像选择成功后触发 avatarUrl: string 仅微信小程序
nickname-change 昵称输入变化时触发(实时) value: string 全平台
nickname-blur 昵称输入失焦时触发(输入完成) value: string 仅微信小程序
nickname-auth 点击昵称区域时触发,用于拉起自定义授权逻辑 - 非微信小程序

# Slots

名称 说明
description 自定义描述内容

# 样式变量

组件提供了下列 CSS 变量,可用于自定义样式。

名称 默认值 说明
--map-authorize-cell-icon-ml $spacing-xs 单元格右边图标左边距
--map-authorize-desc-mb $spacing-lg 描述文本下边距
--map-authorize-avatar-size .8rem 头像大小
--map-authorize-cell-item-height 1.12rem 单元格高度
--map-authorize-cell-icon-size .4rem 单元格右边图标大小
--map-authorize-desc-text-color $color-text-invert-default 描述文字颜色
--map-authorize-label-text-color $color-text-primary 标签文字颜色
--map-authorize-name-text-color $color-text-invert-dark 名称文字颜色
--map-authorize-bg-color none 背景颜色
--map-authorize-cell-border-color $color-divider-light 单元格边框颜色
--map-authorize-desc-font-size $font-size-sm 描述文字大小
--map-authorize-label-font-size $font-size-lg 标签文字大小
--map-authorize-name-font-size $font-size-lg 名称文字大小
--map-authorize-avatar-border-radius $border-radius-circle 头像圆角

# 注意事项

  1. 平台差异
    • 微信小程序:头像使用 open-type="chooseAvatar" 原生能力,昵称输入框支持 type="nickname" 和失焦事件
    • 非微信小程序:头像点击触发 avatar-click 事件,昵称点击触发 nickname-auth 事件,需自行实现授权逻辑
  2. 事件触发时机
    • nickname-change:每次输入都触发(实时变化)
    • nickname-blur:仅在失焦时触发一次(输入完成),仅微信小程序支持
    • avatar-change:微信小程序头像选择成功后自动触发,同时也会触发 avatar-click
  3. 昵称输入框使用了 press-field 组件,支持所有 field 组件的特性
  4. 头像显示优先级:avatarUrl > defaultAvatarUrl
  5. 组件内部会自动处理输入框的样式,保持与整体设计一致
  6. 建议配合弹窗组件使用,提供完整的授权流程体验

# 常见问题

# 如何自定义头像大小?

.custom-authorization {
  --map-authorize-avatar-size: 1rem;
}

# 如何修改单元格高度?

.custom-authorization {
  --map-authorize-cell-item-height: 1.5rem;
}

# 如何隐藏描述文本?

<PressMatchAuthorizationItem
  desc=""
  @avatar-click="handleAvatarClick"
/>

# 如何验证昵称输入?

const handleNicknameBlur = (value) => {
  // 长度验证
  if (value.length < 2 || value.length > 20) {
    wx.showToast({ title: '昵称长度应在2-20个字符之间', icon: 'none' })
    return
  }
  
  // 特殊字符验证
  const regex = /^[\u4e00-\u9fa5a-zA-Z0-9_]+$/
  if (!regex.test(value)) {
    wx.showToast({ title: '昵称只能包含中文、英文、数字和下划线', icon: 'none' })
    return
  }
}

# 如何与其他组件配合使用?

<!-- 在授权弹窗中使用 -->
<PressMatchMpAuthorizePopup :show="showAuth">
  <PressMatchAuthorizationItem
    :avatar-url="avatarUrl"
    :nickname="nickname"
    @avatar-click="handleAvatarClick"
    @avatar-change="handleAvatarChange"
    @nickname-change="handleNicknameChange"
  />
</PressMatchMpAuthorizePopup>