mobile.vue 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. <template>
  2. <view class="container">
  3. <view class="auth-header">
  4. <view class="auth-logo">
  5. <u-avatar size="100" icon="github-circle-fill" fontSize="100"></u-avatar>
  6. </view>
  7. </view>
  8. <view class="auth-box">
  9. <!-- 登录方式选择 -->
  10. <view class="mode-section">
  11. <u-subsection class="subsection" mode="subsection" fontSize="15" :list="loginModeList" :current="currentModeIndex" @change="handleModeChange"></u-subsection>
  12. </view>
  13. <u-gap height="40"></u-gap>
  14. <!-- 登录表单 -->
  15. <u--form labelPosition="left" :model="formData" :rules="rules" ref="form">
  16. <u-form-item label="手机号" prop="mobile" labelWidth="60" borderBottom ref="item-mobile">
  17. <u-input type="number" maxlength="11" v-model="formData.mobile" clearable placeholder="请填写手机号" border="none"></u-input>
  18. </u-form-item>
  19. <u-gap height="20"></u-gap>
  20. <u-form-item v-if="currentModeIndex === 0" label="密码" prop="password" labelWidth="60" borderBottom ref="item-password">
  21. <u-input :type="inputType" maxlength="16" v-model="formData.password" placeholder="请填写密码" border="none">
  22. <template slot="suffix">
  23. <u-icon v-if="inputType === 'password'" size="20" color="#666666" name="eye-fill" @click="inputType = 'text'"></u-icon>
  24. <u-icon v-if="inputType === 'text'" size="20" color="#666666" name="eye-off" @click="inputType = 'password'"></u-icon>
  25. </template>
  26. </u-input>
  27. </u-form-item>
  28. <u-form-item v-else label="验证码" prop="code" labelWidth="60" borderBottom>
  29. <u--input type="number" maxlength="4" v-model="formData.code" border="none" placeholder="请填写验证码"></u--input>
  30. <u-button slot="right" @tap="getCode" :text="codeTips" type="success" size="mini" :disabled="codeDisabled"></u-button>
  31. <u-code ref="uCode" @change="codeChange" seconds="60" @start="codeDisabled = true" @end="codeDisabled = false"></u-code>
  32. </u-form-item>
  33. <view class="btn-group">
  34. <u-button class="auth-btn" type="primary" customStyle="margin-top: 50px" @click="handleSubmit">立即登录</u-button>
  35. </view>
  36. </u--form>
  37. </view>
  38. </view>
  39. </template>
  40. <script>
  41. import { sendSmsCode } from '../../api/auth'
  42. export default {
  43. data() {
  44. return {
  45. currentModeIndex: 0,
  46. loginModeList: ['密码登录', '验证码登录'],
  47. inputType: 'password',
  48. codeDisabled: false,
  49. codeTips: '',
  50. formData: {
  51. mobile: '',
  52. password: '',
  53. code: ''
  54. },
  55. rules: {
  56. mobile: [
  57. {
  58. type: 'integer',
  59. required: true,
  60. message: '请填写手机号',
  61. trigger: ['blur', 'change']
  62. },
  63. {
  64. // 自定义验证函数,见上说明
  65. validator: (rule, value, callback) => {
  66. // 上面有说,返回true表示校验通过,返回false表示不通过
  67. // uni.$u.test.mobile()就是返回true或者false的
  68. return uni.$u.test.mobile(value)
  69. },
  70. message: '手机号码不正确',
  71. // 触发器可以同时用blur和change
  72. trigger: ['change', 'blur']
  73. }
  74. ],
  75. password: {
  76. type: 'string',
  77. min: 4,
  78. max: 16,
  79. required: true,
  80. message: '密码长度4-16位密码',
  81. trigger: ['blur', 'change']
  82. },
  83. code: {
  84. type: 'integer',
  85. len: 4,
  86. required: true,
  87. message: '请填写4位验证码',
  88. trigger: ['blur', 'change']
  89. }
  90. }
  91. }
  92. },
  93. onLoad() {},
  94. onReady() {
  95. // 如果需要兼容微信小程序,并且校验规则中含有方法等,只能通过setRules方法设置规则
  96. this.$refs.form.setRules(this.rules)
  97. },
  98. methods: {
  99. handleModeChange(index) {
  100. if (index !== this.currentModeIndex) {
  101. this.currentModeIndex = index
  102. this.$refs.form.clearValidate()
  103. }
  104. },
  105. codeChange(text) {
  106. this.codeTips = text
  107. },
  108. getCode() {
  109. const mobile = this.formData.mobile
  110. if (!mobile) {
  111. uni.$u.toast('请填写手机号')
  112. } else if (!uni.$u.test.mobile(mobile)) {
  113. uni.$u.toast('手机号格式不正确')
  114. } else if (this.$refs.uCode.canGetCode) {
  115. // 模拟向后端请求验证码
  116. uni.showLoading({
  117. title: '正在获取验证码'
  118. })
  119. //scene:1登陆获取验证码场景
  120. sendSmsCode({ mobile: mobile, scene: 1 }).then(res => {
  121. //console.log(res)
  122. uni.hideLoading()
  123. uni.$u.toast('验证码已发送')
  124. // 通知验证码组件内部开始倒计时
  125. this.$refs.uCode.start()
  126. })
  127. } else {
  128. uni.$u.toast('倒计时结束后再发送')
  129. }
  130. },
  131. handleSubmit() {
  132. this.$refs.form.validate().then(res => {
  133. uni.login({
  134. provider: 'weixin',
  135. success: res => {
  136. let data = this.formData
  137. data.socialType = 34 //WECHAT_MINI_APP 先指定固定值
  138. data.socialCode = res.code
  139. data.socialState = Math.random() // 该参数没有实际意义暂时传随机数
  140. this.mobileLogin(data)
  141. },
  142. fail: res => {
  143. this.mobileLogin(this.formData)
  144. }
  145. })
  146. })
  147. },
  148. mobileLogin(data){
  149. this.$store.dispatch('Login', { type: this.currentModeIndex, data: data }).then(res => {
  150. uni.$u.toast('登录成功')
  151. setTimeout(() => {
  152. uni.switchTab({
  153. url: '/pages/user/user'
  154. })
  155. }, 300)
  156. })
  157. }
  158. }
  159. }
  160. </script>
  161. <style lang="scss" scoped>
  162. .auth-header {
  163. height: 400rpx;
  164. @include flex-center;
  165. .auth-logo {
  166. @include flex-center(column);
  167. }
  168. }
  169. .auth-box {
  170. @include flex-center(column);
  171. .mode-section {
  172. width: 600rpx;
  173. .subsection {
  174. height: 60rpx;
  175. }
  176. }
  177. .btn-group {
  178. width: 600rpx;
  179. .auth-btn {
  180. height: 90rpx;
  181. font-size: 32rpx;
  182. }
  183. }
  184. }
  185. </style>