Login.vue 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. <script setup>
  2. import { User, Lock } from '@element-plus/icons-vue'
  3. import { ref } from 'vue'
  4. // 控制注册与登录表单的显示, 默认显示注册
  5. const isRegister = ref(false)
  6. // 定义注册表单的数据模型,并绑定到对应的标签
  7. const registerData=ref({
  8. username:'',
  9. password:'',
  10. rePassword:''
  11. }
  12. )
  13. // 自定义表单校验规则:校验二次密码是否和第一次输入的一致,参考 element-plus 官方文档编写
  14. const checkRePassword=(rule,value,callback)=>{
  15. if(value===''){
  16. callback(new Error("请再次确认密码!"))
  17. }else if(value!==registerData.value.password){
  18. callback(new Error('请确保两次输入的密码一样!'))
  19. }else{
  20. callback()
  21. }
  22. }
  23. // 定义表单校验规则,由于使用的是 Element-Plus ,所以,表单校验规则需要参考官方文档进行编写
  24. const rules={
  25. username:[
  26. {required:true,message:'请输入用户名',trigger:'blur'},
  27. {min:5,max:16,message:'请输入用户名长度在5-16位非空字符',trigger:'blur'}
  28. ],
  29. password:[
  30. {required:true,message:'请输入密码',trigger:'blur'},
  31. {min:5,max:16,message:'请输入密码长度在5-16位非空字符',trigger:'blur'}
  32. ],
  33. rePassword:[
  34. {validator:checkRePassword,trigger:'blur'}
  35. ]
  36. }
  37. // 美化提示信息
  38. import { ElMessage } from 'element-plus'
  39. // 点击注册按钮后,触发这里的方法,发送请求至后端接口,完成注册
  40. import {userRegisterService,userLoginService} from '@/api/user.js'
  41. const register=async()=>{
  42. // 上面自定义的 registerData 变量是 ref 响应式变量,要想获取值,需要 registerData.value
  43. let result=await userRegisterService(registerData.value)
  44. /*
  45. // 这里的 result.code 和 result.msg ,都是后端开发时,当初定义的返回数据 json 格式。
  46. if(result.code===0){
  47. // 成功了
  48. alert(result.msg?result.msg:'注册成功!')
  49. }else{
  50. // 失败了
  51. alert("注册失败!")
  52. }
  53. */
  54. // 利用改良后的响应拦截器,若代码到这里,则说明成功。
  55. //alert(result.msg?result.msg:'注册成功!')
  56. // 美化提示信息的写法
  57. ElMessage({message: '注册成功!',type: 'success',})
  58. }
  59. // 绑定登录表单数据的时候,复用了注册表单的数据模型,因此这里没有重新定义登录数据模型
  60. // 表单数据校验也是复用注册表单的,也没有创建新的规则
  61. // 使用路由,方便用户点击登录按钮后,能自动跳转主页
  62. import {useRouter} from 'vue-router'
  63. const router=useRouter()
  64. // 为了能记录后端的 token,这里使用 pinia
  65. import {userTokenStore} from '@/stores/token.js'
  66. const tokenStore=userTokenStore();
  67. // 登录功能点击后触发的函数
  68. const login=async()=>{
  69. // 调用接口,完成登录
  70. let result=await userLoginService(registerData.value)
  71. /*
  72. if(result.code===0){
  73. alert(result.msg?result.msg:'登录成功!')
  74. }else{
  75. alert("登录失败!")
  76. }
  77. */
  78. // 利用改良后的响应拦截器,若代码到这里,说明成功
  79. //alert(result.msg?result.msg:'登录成功!')
  80. // 美化提示信息的写法
  81. ElMessage({message: '登录成功!',type: 'success',})
  82. // 记录后端传过来的 token
  83. tokenStore.setToken(result.data);
  84. // 跳转到主界面
  85. router.push('/')
  86. }
  87. // 定义清空数据模型,使用户点击注册或返回按钮时,数据清空
  88. const clearRegisterData=()=>{
  89. registerData.value={
  90. username:'',
  91. password:'',
  92. rePassword:''
  93. }
  94. }
  95. </script>
  96. <template>
  97. <el-row class="login-page">
  98. <el-col :span="12" class="bg"></el-col>
  99. <el-col :span="6" :offset="3" class="form">
  100. <!-- 注册表单,使用 :model 绑定 script 标签中的的表单数据 registerData ,使用 :rules 绑定 rules 表单校验规则 -->
  101. <el-form ref="form" size="large" autocomplete="off" v-if="isRegister" :model="registerData" :rules="rules">
  102. <el-form-item>
  103. <h1>注册</h1>
  104. </el-form-item>
  105. <!--prop 指定使用表单校验规则中 username 那一项-->
  106. <el-form-item prop="username">
  107. <!-- v-model 绑定 script 标签中定义的 registerData.username -->
  108. <el-input :prefix-icon="User" placeholder="请输入用户名" v-model="registerData.username"></el-input>
  109. </el-form-item>
  110. <!--prop 指定使用表单校验规则中 password 那一项-->
  111. <el-form-item prop="password">
  112. <!-- v-model 绑定 script 标签中定义的 registerData.password-->
  113. <el-input :prefix-icon="Lock" type="password" placeholder="请输入密码" v-model="registerData.password"></el-input>
  114. </el-form-item>
  115. <!--prop 指定使用表单校验规则中 rePassword 那一项-->
  116. <el-form-item prop="rePassword">
  117. <!-- v-model 绑定 script 标签中定义的 registerData.rePassword-->
  118. <el-input :prefix-icon="Lock" type="password" placeholder="请输入再次密码" v-model="registerData.rePassword"></el-input>
  119. </el-form-item>
  120. <!-- 注册按钮 -->
  121. <el-form-item>
  122. <!--绑定注册事件-->
  123. <el-button class="button" type="primary" auto-insert-space @click="register">
  124. 注册
  125. </el-button>
  126. </el-form-item>
  127. <el-form-item class="flex">
  128. <!--如果一个点击事件想执行多个函数,用分号分割-->
  129. <el-link type="info" :underline="false" @click="isRegister = false; clearRegisterData()" >
  130. ← 返回
  131. </el-link>
  132. </el-form-item>
  133. </el-form>
  134. <!-- 登录表单 ,这里复用注册表单的 registerData 变量信息,并复用注册表单的校验规则-->
  135. <el-form ref="form" size="large" autocomplete="off" :model="registerData" :rules="rules" v-else>
  136. <el-form-item>
  137. <h1>登录</h1>
  138. </el-form-item>
  139. <!--prop 指定使用表单校验规则中 username 那一项-->
  140. <el-form-item prop="username">
  141. <!--这里复用注册表单的 registerData.username-->
  142. <el-input :prefix-icon="User" placeholder="请输入用户名" v-model="registerData.username"></el-input>
  143. </el-form-item>
  144. <!--prop 指定使用表单校验规则中 password 那一项-->
  145. <el-form-item prop="password">
  146. <!--这里复用注册表单的 registerData.password-->
  147. <el-input name="password" :prefix-icon="Lock" type="password" placeholder="请输入密码" v-model="registerData.password"></el-input>
  148. </el-form-item>
  149. <el-form-item class="flex">
  150. <div class="flex">
  151. <el-checkbox>记住我</el-checkbox>
  152. <el-link type="primary" :underline="false">忘记密码?</el-link>
  153. </div>
  154. </el-form-item>
  155. <!-- 登录按钮 -->
  156. <el-form-item>
  157. <!--添加点击事件,点击后进行登录操作-->
  158. <el-button class="button" type="primary" auto-insert-space @click="login">登录</el-button>
  159. </el-form-item>
  160. <el-form-item class="flex">
  161. <!--如果一个点击事件想执行多个函数,用分号分割-->
  162. <el-link type="info" :underline="false" @click="isRegister = true; clearRegisterData()" >
  163. 注册 →
  164. </el-link>
  165. </el-form-item>
  166. </el-form>
  167. </el-col>
  168. </el-row>
  169. </template>
  170. <style lang="scss" scoped>
  171. /* 样式 */
  172. .login-page {
  173. height: 100vh;
  174. background-color: #fff;
  175. .bg {
  176. background: url('@/assets/logo2.png') no-repeat 60% center / 240px auto,
  177. url('@/assets/login_bg.jpg') no-repeat center / cover;
  178. border-radius: 0 20px 20px 0;
  179. }
  180. .form {
  181. display: flex;
  182. flex-direction: column;
  183. justify-content: center;
  184. user-select: none;
  185. .title {
  186. margin: 0 auto;
  187. }
  188. .button {
  189. width: 100%;
  190. }
  191. .flex {
  192. width: 100%;
  193. display: flex;
  194. justify-content: space-between;
  195. }
  196. }
  197. }
  198. </style>