Uniapp 微信小程序获取微信昵称、头像

技术栈:Uniapp + Vue3 + uview-plus

简介

因实际需求,需要本小程序支持用户修改默认的头像、用户名,其中还需支持获取微信账号的头像、昵称。

原本可直接获取昵称、头像的 wx.getUserInfoopen-type=“getUserInfo” 获取用户个人信息(头像、昵称、性别与地区),权限已经被微信收回。

具体可查看微信官方文档:

  1. wx.getUserInfo(Object object)
  2. 小程序登录、用户信息相关接口调整说明

用户信息接口权限调整

但是微信单独提供了接口来支持替换此功能

  1. getUserProfile
  2. button 配置 open-type=“chooseAvatar” @chooseavatar=“onChooseavatar”
  3. input 配置 type=“nickname”

实现

获取微信头像

为了页面显示效果和功能实现,需要使用 button包裹住头像,button 配置 相关属性,chooseavatar 内接收、处理图片路径。

<up-cell-group>
  <up-cell :isLink="false">
    <template #title> <view class="title">头像</view> </template>
    <template #value>
      <button
        class="avatar-btn"
        style="border-radius: 50%"
        open-type="chooseAvatar"
        @chooseavatar="onChooseavatar"
      >
        <up-avatar :src="infoForm.avatar" :size="64"></up-avatar>
      </button>
    </template>
  </up-cell>
</up-cell-group>
import { reactive } from "vue";

const infoForm = reactive({ avatar: "" });

// 选择头像|手机内其他图片
const onChooseavatar = (e) => {
  new Promise((resolve, reject) => {
  // 获取图片信息(临时路径)
    uni.getImageInfo({
      src: e.detail.avatarUrl,
      success: (res) => {
        // console.log("图片信息", res)
        resolve(res);
      },
      fail: (err) => {
        // console.error("获取图片信息失败了", err)
        reject(err);
      },
    });
  })
    .then((res) => {
      return Promise.resolve({
        tempFilePath: e.detail.avatarUrl,
      });
    })
    .then((res) => {
      infoForm.avatar = e.detail.avatarUrl;
      // 上传头像到服务器
      // return uploadAvatar(res).then((res) => {
      //   infoForm.avatar = res.url; 
      // });
    })
    .catch((err) => {
    	// 获取失败时使用store内默认头像
    	// infoForm.avatar = userStore.userInfo.avatar
    });
};

获取微信昵称

获取微信昵称就相对比较简单,只需要input配置type=“nickname” 即可,其他按照正常逻辑。

<up-form
  labelPosition="left"
  :labelWidth="100"
  :model="infoForm"
  ref="formRef"
>
  <up-form-item
    label="用户名"
    prop="nickName"
    ref="nickName"
    borderBottom
  >
    <up-input
      v-model="infoForm.nickName"
      border="none"
      type="nickname"
      fontSize="28rpx"
      color="#666666"
      clearable
    ></up-input>
  </up-form-item>
</up-form>
import { ref, reactive } from "vue";
const infoForm = reactive({
  nickName: "",
});

效果

最终实现效果
修改用户头像

修改用户昵称

完整代码

修改头像

<template>
  <view class="wrap">
    <div class="edit-main-box">
      <up-cell-group>
        <up-cell :isLink="false">
          <template #title> <view class="title">头像</view> </template>
          <template #value>
            <button
              class="avatar-btn"
              style="border-radius: 50%"
              open-type="chooseAvatar"
              @chooseavatar="onChooseavatar"
            >
              <up-avatar :src="infoForm.avatar" :size="64"></up-avatar>
            </button>
          </template>
          <template #right-icon>
            <image class="Expand_left-img" src="@/static/svg-icons/Expand_left.svg"></image>
		      </template>
        </up-cell>
        <view class="info-line"></view>
        <u-cell :isLink="false" >
          <template #title> <view class="title">用户名</view> </template>
          <template #value
            ><view class="value" @click="toEditName">{{ infoForm.nickName }}</view>
          </template>
          <template #right-icon>
            <image class="Expand_left-img" src="@/static/svg-icons/Expand_left.svg" @click="toEditName"></image>
		      </template>
        </u-cell>
      </up-cell-group>
    </div>
  </view>
</template>
<script setup>
import { reactive } from "vue";
import { onShow } from "@dcloudio/uni-app";
// store中用户信息
import { useUserStore } from "@/stores/user";

const userStore = useUserStore();
const infoForm = reactive({
  avatar: "",
  nickName: "",
});

onShow(() => {
  infoForm.avatar = userStore.userInfo.avatar;
  infoForm.nickName = userStore.userInfo.nickName;
});


// 上传头像
const uploadAvatar = (res) => {
  return new Promise(async (resolve, reject) => {
  	// 上传用户头像到服务器
    // const result = await uploadFile(res.tempFilePath, "user-avatar");
    // resolve({
    //   url: result,
    // });
  });
};

// 选择头像
const onChooseavatar = (e) => {
  new Promise((resolve, reject) => {
    uni.getImageInfo({
      src: e.detail.avatarUrl,
      success: (res) => {
        // console.log("图片尺寸", res)
        resolve(res);
      },
      fail: (err) => {
        // console.error("获取图片信息失败了", err)
        reject(err);
      },
    });
  })
    .then((res) => {
      return Promise.resolve({
        tempFilePath: e.detail.avatarUrl,
      });
    })
    .then((res) => {
      infoForm.avatar = e.detail.avatarUrl;
      return uploadAvatar(res).then((res) => {
        infoForm.avatar = res.url;
        updateInfo();
      });
    })
    .catch((err) => (infoForm.avatar = userStore.userInfo.avatar)); // 失败恢复
};

// 去编辑用户名页面
const toEditName = () => {
  // router.navigateTo("/pages/editInfo/editName", {
  //   defaultNickName: infoForm.nickName,
  // });
};

</script>
<style scoped lang="scss">
.wrap {
  background-color: #f3f4f6;
  min-height: 100vh;
  padding: 0 28rpx;
  // padding-bottom: 150rpx;
  padding-top: 28rpx;
}
.edit-main-box {
  // margin: 20rpx 28rpx;
  background: #fff;
  border-radius: 8px;
  .info-line {
    width: calc(100% - 56rpx);
    margin: 0 28rpx;
    height: 2rpx;
    background: #f5f5f6;
  }
  :deep(.u-line) {
    display: none;
  }
  .avatar-btn {
    padding: 0;
    border-radius: 50%;
  }
  .title {
    font-family: "PingFang SC";
    font-size: 28rpx;
    font-weight: 500;
    line-height: normal;
    color: #333333;
    width: 150rpx;
  }
  .value {
    font-family: "PingFang SC";
    font-size: 28rpx;
    font-weight: normal;
    line-height: normal;
    letter-spacing: 0px;
    font-variation-settings: "opsz" auto;
    color: #666666;
  }
  .Expand_left-img {
    width: 44rpx;
    height: 44rpx;
  }
}
</style>

修改昵称

<template>
  <view class="wrap">
    <up-toast ref="uToastRef"></up-toast>
    <view class="main-box">
      <up-form
        labelPosition="left"
        :labelStyle="labelStyle"
        :labelWidth="100"
        :model="infoForm"
        ref="formRef"
      >
        <up-form-item
          label="用户名"
          prop="nickName"
          ref="nickName"
          borderBottom
        >
          <up-input
            v-model="infoForm.nickName"
            border="none"
            type="nickname"
            fontSize="28rpx"
            color="#666666"
            clearable
            @change="changeInput"
          ></up-input>
        </up-form-item>
      </up-form>
    </view>
    <view class="edit-name-limit">用户名限制1-20个字符</view>
    <view class="btn-edit-name">
      <button
        class="btn-edit-name-btn"
        :style="{ opacity: isDis ? 0.2 : 1 }"
        :disabled="isDis"
        @click="updateInfo"
      >
        确定
      </button>
    </view>
  </view>
</template>
<script setup>
import { ref, reactive } from "vue";
import { onLoad } from "@dcloudio/uni-app";
// store中用户信息
import { useUserStore } from "@/stores/user";

const infoForm = reactive({
  nickName: "",
});

const uToastRef = ref(null);
const userStore = useUserStore();
const isDis = ref(false);

const labelStyle = ref({
  "font-size": "28rpx",
  "font-weight": 600,
  color: "#3B3D3D",
});

onLoad(() => {
  infoForm.nickName = userStore.userInfo.nickName;
});

// 输入为空时禁用
const changeInput = (value) => {
  if (!value) isDis.value = true;
  else isDis.value = false;
}

// 更新用户名
const updateInfo = () => {
  if (infoForm.nickName.length > 20) {
    // ("用户名太长,最多20个字符"); // uniapp弹窗
    uToastRef.value.show({  
      type: 'default',
	  message: "用户名太长,最多20个字符",
    });  
    return;
  }
  // 请求更新用户信息接口
};
</script>
<style scoped lang="scss">
.wrap {
  background-color: #f3f4f6;
  min-height: 100vh;
  padding: 0 28rpx;
  padding-top: 28rpx;
  // padding-bottom: 150rpx;
  .main-box {
    background: #fff;
    border-radius: 8px;
    padding: 10rpx 14rpx;
    :deep(.u-line) {
      display: none;
    }
  }
  .edit-name-limit {
    font-family: "PingFang SC";
    font-size: 12px;
    color: #999999;
    margin-top: 32rpx;
    margin-bottom: 80rpx;
  }
  .btn-edit-name-btn {
    width: 100%;
    border-radius: 8px;
    background: #ff0046;
    height: 96rpx;
    border-radius: 8px;
    padding-top: 28rpx;
    padding-bottom: 28rpx;
    font-family: "PingFang SC";
    font-weight: 500;
    line-height: normal;
    font-size: 28rpx;
    color: #ffffff;
    border: none;
    &::after {
      border: unset;
    }
  }
  .btn-edit-name-btn:disabled {
    cursor: not-allowed; /* 更改鼠标指针为禁止符号 */
    background: rgba(255, 0, 70, 0.2);
    box-shadow: none; /* 移除阴影 */
    /* 可以添加其他属性来进一步更改按钮的禁用样式,如边框颜色、文本颜色等 */
  }
}
</style>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值