c-pop-login.vue 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. <template>
  2. <view class="mask" :class="isLogin ? 'none' : !isLogin ? 'show' : ''">
  3. <view class="mask-content" @click.stop.prevent="stopPrevent">
  4. <view class="c-input-wrap">
  5. <u-input class="inner_input" fontSize="26rpx" placeholderClass="plac" placeholder="请输入手机号" border="none" v-model="form.phone" clearable></u-input>
  6. </view>
  7. <view class="c-input-wrap">
  8. <u-input class="inner_input" fontSize="26rpx" placeholderClass="plac" placeholder="请输入验证码" border="none" v-model="form.code"></u-input>
  9. <view class="divide"></view>
  10. <view class="tip-btn" :class="{disable: send}" @click="getCode">{{tips}}</view>
  11. </view>
  12. <u-button type="primary" shape="circle" class="c-button" text="登录" @click="loginAction"></u-button>
  13. </view>
  14. <u-code :seconds="seconds" @end="end" @start="start" ref="uCode" @change="codeChange"></u-code>
  15. <u-toast ref="uToast"></u-toast>
  16. </view>
  17. </template>
  18. <script>
  19. import { mapActions, mapState, mapGetters } from 'vuex';
  20. export default {
  21. name:"c-pop-login",
  22. data() {
  23. return {
  24. tips: '获取验证码',
  25. seconds: 60,
  26. send: false,
  27. form: {
  28. phone: '',
  29. code: '',
  30. }
  31. };
  32. },
  33. props: {
  34. onComplate: {
  35. type: Function,
  36. default: () => { }
  37. },
  38. },
  39. computed: {
  40. ...mapGetters(['isLogin']),
  41. },
  42. mounted() {
  43. },
  44. methods: {
  45. ...mapActions({
  46. 'login': 'login',
  47. 'loginRefresh': 'loginRefresh',
  48. }),
  49. stopPrevent(){
  50. },
  51. codeChange(text) {
  52. this.tips = text;
  53. },
  54. getCode() {
  55. if(this.$refs.uCode.canGetCode) {
  56. // 模拟向后端请求验证码
  57. this.$refs.uToast.show({
  58. type: 'loading',
  59. message: '正在获取验证码',
  60. })
  61. // TODO 发起请求:
  62. this.$api('h5.getCode', {mobile: this.form.phone}).then(res => {
  63. console.log(res)
  64. this.$refs.uToast.hide()
  65. if(res.code == 1){
  66. // 这里此提示会被this.start()方法中的提示覆盖
  67. uni.$u.toast('验证码已发送')
  68. // 通知验证码组件内部开始倒计时
  69. this.$refs.uCode.start()
  70. }
  71. })
  72. } else {
  73. uni.$u.toast('倒计时结束后再发送');
  74. }
  75. },
  76. end() {
  77. this.send = false;
  78. },
  79. start() {
  80. this.send = true;
  81. },
  82. loginAction() {
  83. this.$refs.uToast.show({
  84. type: 'loading',
  85. message: '正在登录,请稍后',
  86. })
  87. this.login({mobile: this.form.phone, code: this.form.code}).then(res => {
  88. this.$refs.uToast.hide()
  89. if(res.code == 1){
  90. // 这里此提示会被this.start()方法中的提示覆盖
  91. uni.$u.toast('登录成功')
  92. // 通知验证码组件内部开始倒计时
  93. this.$refs.uCode.start()
  94. }
  95. this.onComplate()
  96. })
  97. }
  98. },
  99. }
  100. </script>
  101. <style lang="scss" scoped>
  102. .mask{
  103. display: flex;
  104. align-items: center;
  105. justify-content: center;
  106. position: fixed;
  107. left: 0;
  108. top: var(--window-top);
  109. bottom: 0;
  110. width: 100vw;
  111. background: rgba(0,0,0,0);
  112. z-index: 10001;
  113. transition: .3s;
  114. .mask-content{
  115. padding-top: 60rpx;
  116. display: flex;
  117. flex-direction: column;
  118. width: 590rpx;
  119. max-height: 45vh;
  120. min-height: 361rpx;
  121. background: #fff;
  122. border-radius: 15px;
  123. }
  124. &.none{
  125. display: none;
  126. }
  127. &.show{
  128. background: rgba(0,0,0,.4);
  129. .mask-content{
  130. transform: translateY(0);
  131. }
  132. }
  133. }
  134. .c-button {
  135. color: #fff;
  136. width: 510rpx;
  137. margin-top: 20rpx;
  138. }
  139. .c-input-wrap{
  140. margin: 0 auto;
  141. width: 510rpx;
  142. height: 70rpx;
  143. background-color: #F0F2F4;
  144. border-radius: 35px;
  145. padding: 0 14px;
  146. box-sizing: border-box;
  147. margin-bottom: 30rpx;
  148. display: flex;
  149. align-items: center;
  150. .divide{
  151. width: 1px;
  152. height: 40rpx;
  153. border-left: 1px solid #FD8701;
  154. }
  155. .tip-btn{
  156. text-align: center;
  157. min-width: 178rpx;
  158. flex-shrink: 0;
  159. font-size: 24rpx;
  160. font-family: PingFang SC;
  161. font-weight: 500;
  162. color: #FD8701;
  163. &.disable{
  164. color: #999;
  165. }
  166. }
  167. & /deep/ .inner_input{
  168. display: flex;
  169. height: 100%;
  170. }
  171. }
  172. </style>