ChangePassword.vue 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. <template>
  2. <div class="change-password-panel">
  3. <form @submit.prevent="onSubmit" class="password-form">
  4. <div class="form-group">
  5. <label>原密码</label>
  6. <input
  7. type="password"
  8. v-model="form.oldPassword"
  9. placeholder="请输入原密码"
  10. required
  11. class="tech-input"
  12. />
  13. </div>
  14. <div class="form-group">
  15. <label>新密码</label>
  16. <input
  17. type="password"
  18. v-model="form.newPassword"
  19. placeholder="请输入新密码 (至少6位)"
  20. required
  21. minlength="6"
  22. class="tech-input"
  23. />
  24. </div>
  25. <div class="form-group">
  26. <label>确认新密码</label>
  27. <input
  28. type="password"
  29. v-model="form.confirmPassword"
  30. placeholder="请再次输入新密码"
  31. required
  32. class="tech-input"
  33. />
  34. <span v-if="passwordMismatch" class="error-msg">两次输入的新密码不一致</span>
  35. </div>
  36. <div class="button-group">
  37. <button type="button" class="btn btn-cancel" @click="onCancel">取消</button>
  38. <button type="submit" class="btn btn-confirm" :disabled="passwordMismatch">确认修改</button>
  39. </div>
  40. </form>
  41. </div>
  42. </template>
  43. <script>
  44. export default {
  45. name: 'ChangePassword',
  46. props: {
  47. onSuccess: {
  48. type: Function,
  49. default: null
  50. },
  51. onCancel: {
  52. type: Function,
  53. default: null
  54. }
  55. },
  56. data() {
  57. return {
  58. form: {
  59. oldPassword: '',
  60. newPassword: '',
  61. confirmPassword: ''
  62. }
  63. }
  64. },
  65. computed: {
  66. // 实时校验两次新密码是否一致
  67. passwordMismatch() {
  68. if (!this.form.newPassword || !this.form.confirmPassword) return false;
  69. return this.form.newPassword !== this.form.confirmPassword;
  70. }
  71. },
  72. methods: {
  73. onSubmit() {
  74. if (this.passwordMismatch) return;
  75. // 在这里派发事件或者调用 API
  76. console.log('提交的密码表单:', this.form);
  77. // 直接调用传进来的 onSuccess 函数
  78. if (typeof this.onSuccess === 'function') {
  79. this.onSuccess(this.form);
  80. }
  81. },
  82. handleCancel() {
  83. // 直接调用传进来的 onCancel 函数
  84. if (typeof this.onCancel === 'function') {
  85. this.onCancel();
  86. }
  87. }
  88. }
  89. }
  90. </script>
  91. <style scoped>
  92. .change-password-panel {
  93. width: 100%;
  94. height: 100%;
  95. display: flex;
  96. flex-direction: column;
  97. padding: 10px;
  98. box-sizing: border-box;
  99. }
  100. .password-form {
  101. display: flex;
  102. flex-direction: column;
  103. gap: 20px;
  104. flex: 1;
  105. }
  106. .form-group {
  107. display: flex;
  108. flex-direction: column;
  109. gap: 8px;
  110. position: relative;
  111. }
  112. .form-group label {
  113. color: #e2e8f0;
  114. font-size: 14px;
  115. letter-spacing: 1px;
  116. }
  117. /* 科技风输入框 */
  118. .tech-input {
  119. width: 100%;
  120. height: 38px;
  121. background-color: rgba(0, 0, 0, 0.2);
  122. border: 1px solid rgba(161, 190, 255, 0.4);
  123. border-radius: 4px;
  124. padding: 0 12px;
  125. color: #ffffff;
  126. font-size: 14px;
  127. outline: none;
  128. transition: all 0.3s ease;
  129. box-sizing: border-box;
  130. }
  131. .tech-input::placeholder {
  132. color: rgba(255, 255, 255, 0.3);
  133. }
  134. .tech-input:focus {
  135. border-color: #3b74ff;
  136. box-shadow: 0 0 8px rgba(59, 116, 255, 0.5);
  137. background-color: rgba(0, 0, 0, 0.4);
  138. }
  139. .error-msg {
  140. position: absolute;
  141. bottom: -18px;
  142. left: 0;
  143. color: #ff4d4f;
  144. font-size: 12px;
  145. }
  146. /* ================= 按钮样式 ================= */
  147. .button-group {
  148. margin-top: auto;
  149. padding-top: 20px;
  150. display: flex;
  151. justify-content: flex-end;
  152. gap: 12px;
  153. }
  154. .btn {
  155. height: 36px;
  156. padding: 0 24px;
  157. font-size: 14px;
  158. border-radius: 4px;
  159. cursor: pointer;
  160. transition: all 0.2s;
  161. border: none;
  162. outline: none;
  163. }
  164. .btn:disabled {
  165. opacity: 0.5;
  166. cursor: not-allowed;
  167. }
  168. .btn-cancel {
  169. background-color: transparent;
  170. color: #d1d5db;
  171. border: 1px solid rgba(130, 150, 190, 0.4);
  172. }
  173. .btn-cancel:hover:not(:disabled) {
  174. color: #ffffff;
  175. border-color: rgba(130, 150, 190, 0.8);
  176. background-color: rgba(255, 255, 255, 0.05);
  177. }
  178. .btn-confirm {
  179. background-color: #3b74ff;
  180. color: #ffffff;
  181. }
  182. .btn-confirm:hover:not(:disabled) {
  183. background-color: #5a8bff;
  184. box-shadow: 0 2px 8px rgba(59, 116, 255, 0.3);
  185. }
  186. </style>