tuniaoui-wx-user-info.vue 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329
  1. <template>
  2. <view
  3. v-if="openModal"
  4. class="wx-authorization-modal"
  5. >
  6. <view
  7. class="wam__mask"
  8. @touchmove.prevent=""
  9. @tap.stop="closeModal"
  10. ></view>
  11. <!-- 内容区域 -->
  12. <view class="wam__wrapper">
  13. <!-- 关闭按钮 -->
  14. <view class="wam__close-btn" @tap.stop="closeModal">
  15. <text class="tn-icon-close"></text>
  16. </view>
  17. <!-- 标题 -->
  18. <view class="wam__title">获取您的昵称、头像</view>
  19. <!-- tips -->
  20. <view class="wam__sub-title">
  21. 获取用户头像、昵称,主要用于向用户提供具有辨识度的用户中心界面
  22. </view>
  23. <!-- 头像选择 -->
  24. <view class="wam__avatar">
  25. <view class="button-shadow">
  26. <button
  27. class="button"
  28. open-type="chooseAvatar"
  29. @chooseavatar="chooseAvatarEvent"
  30. >
  31. <view v-if="userInfo.avatar" class="avatar__image">
  32. <image class="image" :src="userInfo.avatar" mode="aspectFill"></image>
  33. </view>
  34. <view v-else class="avatar__empty">
  35. <image class="image" src="https://cdn.nlark.com/yuque/0/2022/jpeg/280373/1668928062708-assets/web-upload/764843cf-055a-4cb6-b5d3-dca528b33fd4.jpeg" mode="aspectFill"></image>
  36. </view>
  37. <view class="avatar--icon">
  38. <view class="tn-icon-camera-fill"></view>
  39. </view>
  40. </button>
  41. </view>
  42. </view>
  43. <!-- 昵称输入 -->
  44. <view class="wam__nickname">
  45. <view class="nickname__data">
  46. <input class="input" type="nickname" v-model="userInfo.nickname" placeholder="请输入昵称" placeholder-style="color: #AAAAAA;">
  47. </view>
  48. </view>
  49. <!-- 保存按钮 -->
  50. <view
  51. class="wam__submit-btn"
  52. :class="[{
  53. 'disabled': !userInfo.avatar || !userInfo.nickname
  54. }]"
  55. hover-class="tn-btn-hover-class"
  56. :hover-stay-time="150"
  57. @tap.stop="submitUserInfo"
  58. >
  59. 保 存
  60. </view>
  61. </view>
  62. </view>
  63. </template>
  64. <script>
  65. export default {
  66. options: {
  67. // 在微信小程序中将组件节点渲染为虚拟节点,更加接近Vue组件的表现(不会出现shadow节点下再去创建元素)
  68. virtualHost: true
  69. },
  70. props: {
  71. value: {
  72. type: Boolean,
  73. default: false
  74. }
  75. },
  76. data() {
  77. return {
  78. openModal: false,
  79. userInfo: {
  80. avatar: '',
  81. nickname: ''
  82. }
  83. }
  84. },
  85. watch: {
  86. value: {
  87. handler(val) {
  88. this.openModal = val
  89. },
  90. immediate: true
  91. }
  92. },
  93. methods: {
  94. // 头像选择
  95. chooseAvatarEvent(e) {
  96. this.userInfo.avatar = e.detail.avatarUrl
  97. },
  98. // 更新用户信息
  99. submitUserInfo() {
  100. // 判断是否已经选择了用户头像和输入了用户昵称
  101. if (!this.userInfo.avatar || !this.userInfo.nickname) {
  102. return uni.showToast({
  103. icon: 'none',
  104. title: '请选择头像和输入用户信息'
  105. })
  106. }
  107. // 更新完成事件
  108. this.$emit('updated', this.userInfo)
  109. },
  110. // 关闭弹框
  111. closeModal() {
  112. this.$emit('input', false)
  113. },
  114. }
  115. }
  116. </script>
  117. <style lang="scss" scoped>
  118. @import '../../static/iconfont.css';
  119. .wx-authorization-modal {
  120. position: fixed;
  121. left: 0;
  122. top: 0;
  123. width: 100vw;
  124. height: 100vh;
  125. z-index: 99998;
  126. view {
  127. box-sizing: border-box;
  128. }
  129. .image {
  130. width: 100%;
  131. height: 100%;
  132. border-radius: inherit;
  133. }
  134. .wam {
  135. /* mask */
  136. &__mask {
  137. position: absolute;
  138. left: 0;
  139. top: 0;
  140. width: 100%;
  141. height: 100%;
  142. background-color: rgba(0, 0, 0, 0.5);
  143. opacity: 0;
  144. animation: showMask 0.25s ease 0.1s forwards;
  145. }
  146. /* close-btn */
  147. &__close-btn {
  148. position: absolute;
  149. top: 30rpx;
  150. right: 30rpx;
  151. z-index: 99999;
  152. }
  153. /* wrapper */
  154. &__wrapper {
  155. position: absolute;
  156. left: 0;
  157. bottom: 0;
  158. width: 100%;
  159. background-color: #FFFFFF;
  160. border-radius: 20rpx 20rpx 0rpx 0rpx;
  161. padding: 40rpx;
  162. padding-top: 60rpx;
  163. padding-bottom: 40rpx;
  164. padding-bottom: calc(constant(safe-area-inset-bottom) + 40rpx);
  165. padding-bottom: calc(env(safe-area-inset-bottom) + 40rpx);
  166. transform-origin: center bottom;
  167. transform: scaleY(0);
  168. animation: showWrapper 0.25s ease 0.1s forwards;
  169. z-index: 99999;
  170. }
  171. /* title */
  172. &__title {
  173. font-size: 34rpx;
  174. }
  175. /* sub-title */
  176. &__sub-title {
  177. font-size: 26rpx;
  178. color: #AAAAAA;
  179. margin-top: 16rpx;
  180. padding-bottom: 30rpx;
  181. }
  182. /* 头像选择 */
  183. &__avatar {
  184. width: 100%;
  185. margin-top: 30rpx;
  186. display: flex;
  187. align-items: center;
  188. justify-content: center;
  189. .button-shadow {
  190. border: 8rpx solid rgba(255,255,255,0.05);
  191. box-shadow: 0rpx 0rpx 80rpx 0rpx rgba(0, 0, 0, 0.15);
  192. border-radius: 50%;
  193. }
  194. .button {
  195. position: relative;
  196. width: 160rpx;
  197. height: 160rpx;
  198. border-radius: 50%;
  199. overflow: visible;
  200. background-image: repeating-linear-gradient(45deg, #E4E9EC, #F8F7F8);
  201. color: #FFFFFF;
  202. background-color: transparent;
  203. padding: 0;
  204. margin: 0;
  205. font-size: inherit;
  206. line-height: inherit;
  207. border: none;
  208. &::after {
  209. border: none;
  210. }
  211. }
  212. .avatar {
  213. &__empty, &__image {
  214. width: 100%;
  215. height: 100%;
  216. border-radius: inherit;
  217. }
  218. &--icon {
  219. position: absolute;
  220. right: -10rpx;
  221. bottom: -6rpx;
  222. width: 60rpx;
  223. height: 60rpx;
  224. // transform: translate(50%, 50%);
  225. background-color: #1D2541;
  226. color: #FFFFFF;
  227. border-radius: 50%;
  228. border: 6rpx solid #FFFFFF;
  229. line-height: 1;
  230. font-size: 36rpx;
  231. display: flex;
  232. align-items: center;
  233. justify-content: center;
  234. }
  235. }
  236. }
  237. /* 昵称 */
  238. &__nickname {
  239. margin-top: 40rpx;
  240. .nickname {
  241. &__data {
  242. margin-top: 16rpx;
  243. width: 100%;
  244. padding: 26rpx 20rpx;
  245. border-radius: 10rpx;
  246. background-color: #F8F7F8;
  247. .input {
  248. color: #080808;
  249. }
  250. }
  251. }
  252. }
  253. /* 保存按钮 */
  254. &__submit-btn {
  255. width: 100%;
  256. background-color: #05C160;
  257. color: #FFFFFF;
  258. margin-top: 60rpx;
  259. border-radius: 10rpx;
  260. padding: 25rpx;
  261. font-size: 32rpx;
  262. display: flex;
  263. align-items: center;
  264. justify-content: center;
  265. &.disabled {
  266. background-color: #E6E6E6;
  267. }
  268. }
  269. }
  270. }
  271. .tn-btn-hover-class {
  272. box-shadow: inset 10rpx 2rpx 40rpx 0rpx rgba(0, 0, 0, 0.05);
  273. }
  274. @keyframes showMask {
  275. 0% {
  276. opacity: 0;
  277. }
  278. 100% {
  279. opacity: 1;
  280. }
  281. }
  282. @keyframes showWrapper {
  283. 0% {
  284. transform: scaleY(0);
  285. }
  286. 100% {
  287. transform: scaleY(1);
  288. }
  289. }
  290. </style>