当前位置:   article > 正文

vue3.0项目实战系列文章 - 登录页面_vue3 登录页面

vue3 登录页面

系列文章目录

   第一章 

论vue3.0和vue2.0区别之编程方式及例子详解

第二章

同一台电脑 实现 vue-cli2和vue-cli3同时并存 及 常见命令

第三章

vue3.0项目实战 - ElementUI框架版

第四章

【TypeScript】在vue3中遇到的问题及解决方案,未完待续

第五章

vue3.0项目实战系列文章 - 登录页面

第六章

vue3.0项目实战系列文章 - 使用周期函数


目录

系列文章目录

前言

一、关于setup?

1.Vue3 的一大特性函数 ---- setup

2.为什么使用setup?

二、登录页面两种写法

1.展示

2.普通的

3.使用单文件组件

总结


前言

坑千千万,踩好才有完美的框架~


一、关于setup

1.Vue3 的一大特性函数 ---- setup

  • setup函数是处于 生命周期函数 beforeCreate 和 Created 之前的函数 也就说在 setup函数中是无法 使用 data 和 methods 中的数据和方法的
  • setup函数是 Composition API(组合API)的入口
  • 在setup函数中定义的变量和方法最后都是需要 return 出去的 不然无法在模板中使用

2.为什么使用setup?

  • data、computed、methods、watch 组织逻辑在大多数情况下都有效。然而,当我们的组件变得更大时,逻辑关注点的列表也会增长。这可能会导致组件难以阅读和理解,尤其是对于那些一开始就没有编写这些组件的人来说简直是噩梦。而通过setup可以将该部分抽离成函数,让其他开发者就不用关心该部分逻辑了。
  • 写一个大型组件时,逻辑关注点的列表很长,不利于维护和阅读;所以需要把一个逻辑关注点的代码收集在一起会更好,由此诞生组合式API,即vue中用到的setup。

二、登录页面两种写法

1.展示

一定要明确好使用哪套,两套并不是内容、特性通用! 

2.普通的<script>

  • 一个组件选项,在组件被创建之前props 被解析之后执行。它是组合式 API 的入口。
  • 注意此种写法需要return
  1. <script lang="ts">
  2. export default {
  3. setup() {
  4. }
  5. }
  6. </script>

整体代码

  1. <template>
  2. <div class="login-wrap">
  3. <div class="ms-login">
  4. <div class="ms-title">后台管理系统</div>
  5. <el-form ref="ruleFormRef" :model="ruleForm" :rules="rules" label-width="0px" class="ms-content">
  6. <el-form-item prop="username">
  7. <el-input v-model="ruleForm.username" placeholder="username">
  8. <template #prepend>
  9. <el-button icon="el-icon-user"></el-button>
  10. </template>
  11. </el-input>
  12. </el-form-item>
  13. <el-form-item prop="password">
  14. <el-input type="password" placeholder="password" v-model="ruleForm.password">
  15. <template #prepend>
  16. <el-button icon="el-icon-lock"></el-button>
  17. </template>
  18. </el-input>
  19. </el-form-item>
  20. <div class="login-btn">
  21. <el-button type="primary" @click="submitForm(ruleFormRef)">登录</el-button>
  22. </div>
  23. <p class="login-tips">Tips : 用户名和密码随便填。</p>
  24. </el-form>
  25. </div>
  26. </div>
  27. </template>
  28. <script lang="ts">
  29. import {
  30. ref,
  31. reactive
  32. } from "vue";
  33. import {
  34. useStore
  35. } from "vuex";
  36. import {
  37. useRouter
  38. } from "vue-router";
  39. import {
  40. ElMessage
  41. } from "element-plus";
  42. import {
  43. roleList
  44. } from "../request/api.js";
  45. export default {
  46. setup() {
  47. const router = useRouter();
  48. const ruleForm = reactive({
  49. username: "admin",
  50. password: "123123",
  51. });
  52. const rules = {
  53. username: [{
  54. required: true,
  55. message: "请输入用户名",
  56. trigger: "blur",
  57. }],
  58. password: [{
  59. required: true,
  60. message: "请输入密码",
  61. trigger: "blur"
  62. }],
  63. }; // 一个普通对象,修改后不会被proxy拦截,进而页面也不会动态更新
  64. const ruleFormRef = ref('');
  65. const submitForm = async (formEl) => {
  66. if (!formEl) return
  67. formEl.validate((valid) => {
  68. if (valid) {
  69. submitFormLink();
  70. } else {
  71. ElMessage.error("登录失败");
  72. return false;
  73. }
  74. });
  75. };
  76. // 使用响应式函数reactive构建proxy响应式对象
  77. const params = reactive({
  78. pageNum: 1,
  79. pageSize: 10,
  80. systemFlag: 'water'
  81. })
  82. const submitFormLink = () => {
  83. roleList(params).then(res => {
  84. if (res.code == 0) {
  85. ElMessage({
  86. showClose: true,
  87. message: '登录成功',
  88. type: 'success',
  89. })
  90. // ElMessage.success('登录成功')
  91. localStorage.setItem("ms_username", ruleForm.username);
  92. router.push("/");
  93. } else if (res.code !== 0) {
  94. ElMessage.error(res.msg)
  95. }
  96. })
  97. };
  98. const store = useStore();
  99. store.commit("clearTags");
  100. // 使用时,要把对象return出去,才能在template中使用
  101. return {
  102. ruleForm,
  103. rules,
  104. ruleFormRef,
  105. submitForm,
  106. params,
  107. submitFormLink
  108. };
  109. },
  110. };
  111. </script>
  112. <style scoped>
  113. </style>

3.使用单文件组件<script setup>

  • 当使用 <script setup> 的时候,任何在 <script setup> 声明的顶层的绑定 (包括变量,函数声明,以及 import 引入的内容) 都能在模板中直接使用
  • 注意此种写法不需要return
  • import 导入的内容也会以同样的方式暴露。意味着可以在模板表达式中直接使用导入的 helper 函数,并不需要通过 methods 选项来暴露它
  • 响应式状态需要明确使用响应式 APIs 来创建。和从 setup() 函数中返回值一样,ref 值在模板中使用的时候会自动解包
  • 在 <script setup> 中必须使用 defineProps 和 defineEmits API 来声明 props 和 emits ,它们具备完整的类型推断并且在 <script setup> 中是直接可用的
    1. <script setup>
    2. const props = defineProps({
    3. foo: String
    4. })
    5. const emit = defineEmits(['change', 'delete'])
    6. // setup code
    7. </script>
  • <script setup> 范围里的值也能被直接作为自定义组件的标签名使用
  1. <script setup>
  2. import MyComponent from './MyComponent.vue'
  3. </script>
  4. <template>
  5. <MyComponent />
  6. </template>
  • 动态组件:由于组件被引用为变量而不是作为字符串键来注册的,在 <script setup> 中要使用动态组件的时候,就应该使用动态的 :is 来绑定

  • 在 <script setup> 中必须使用 defineProps 和 defineEmits API 来声明 props 和 emits ,它们具备完整的类型推断并且在 <script setup> 中是直接可用的

本登录页面使用

  1. <script lang="ts" setup>
  2. </script>

 整体代码

  1. <template>
  2. <div class="login-wrap">
  3. <div class="ms-login">
  4. <div class="ms-title">德润厚天项目管理系统</div>
  5. <el-form ref="ruleFormRef" :model="ruleForm" :rules="rules" label-width="0px" class="ms-content">
  6. <el-form-item prop="username">
  7. <el-input v-model="ruleForm.username" placeholder="username">
  8. <template #prepend>
  9. <el-button icon="el-icon-user"></el-button>
  10. </template>
  11. </el-input>
  12. </el-form-item>
  13. <el-form-item prop="password">
  14. <el-input type="password" placeholder="password" v-model="ruleForm.password">
  15. <template #prepend>
  16. <el-button icon="el-icon-lock"></el-button>
  17. </template>
  18. </el-input>
  19. </el-form-item>
  20. <div class="login-btn">
  21. <el-button type="primary" @click="submitForm(ruleFormRef)">登录</el-button>
  22. </div>
  23. <p class="login-tips">Tips : 用户名和密码随便填。</p>
  24. </el-form>
  25. </div>
  26. </div>
  27. </template>
  28. <script lang="ts" setup>
  29. import {
  30. ref,
  31. reactive
  32. } from "vue";
  33. import {
  34. useStore
  35. } from "vuex";
  36. import {
  37. useRouter
  38. } from "vue-router";
  39. import {
  40. ElMessage
  41. } from "element-plus";
  42. import {
  43. roleList
  44. } from "../../request/api.js";
  45. const router = useRouter();
  46. const ruleForm = reactive({
  47. username: "admin",
  48. password: "123123",
  49. });
  50. const rules = {
  51. username: [{
  52. required: true,
  53. message: "请输入用户名",
  54. trigger: "blur",
  55. }],
  56. password: [{
  57. required: true,
  58. message: "请输入密码",
  59. trigger: "blur"
  60. }],
  61. }; // 一个普通对象,修改后不会被proxy拦截,进而页面也不会动态更新
  62. const ruleFormRef = ref('');
  63. const submitForm = async (formEl) => {
  64. if (!formEl) return
  65. formEl.validate((valid) => {
  66. if (valid) {
  67. submitFormLinkFree();
  68. } else {
  69. ElMessage.error("登录失败");
  70. return false;
  71. }
  72. });
  73. };
  74. // 使用响应式函数reactive构建proxy响应式对象
  75. const params = reactive({
  76. pageNum: 1,
  77. pageSize: 10,
  78. systemFlag: 'water'
  79. })
  80. const submitFormLink = () => {
  81. roleList(params).then(res => {
  82. if (res.code == 0) {
  83. ElMessage({
  84. showClose: true,
  85. message: '登录成功',
  86. type: 'success',
  87. })
  88. // ElMessage.success('登录成功')
  89. localStorage.setItem("ms_username", ruleForm.username);
  90. router.push("/");
  91. } else if (res.code !== 0) {
  92. ElMessage.error(res.msg)
  93. }
  94. })
  95. };
  96. const submitFormLinkFree = () => {
  97. ElMessage({
  98. showClose: true,
  99. message: '登录成功',
  100. type: 'success',
  101. })
  102. localStorage.setItem("ms_username", ruleForm.username);
  103. router.push("/");
  104. };
  105. const store = useStore();
  106. store.commit("clearTags");
  107. </script>
  108. <style scoped>
  109. .login-wrap {
  110. position: relative;
  111. width: 100%;
  112. height: 100%;
  113. background: url(../../assets/img/login-bg.jpg) no-repeat;
  114. background-size: 100% 100%;
  115. }
  116. .ms-title {
  117. width: 100%;
  118. line-height: 50px;
  119. text-align: center;
  120. font-size: 20px;
  121. color: #fff;
  122. border-bottom: 1px solid #ddd;
  123. }
  124. .ms-login {
  125. position: absolute;
  126. left: 50%;
  127. top: 50%;
  128. width: 350px;
  129. margin: -190px 0 0 -175px;
  130. border-radius: 5px;
  131. background: rgba(255, 255, 255, 0.3);
  132. overflow: hidden;
  133. }
  134. .ms-content {
  135. padding: 30px 30px;
  136. }
  137. .login-btn {
  138. text-align: center;
  139. }
  140. .login-btn button {
  141. width: 100%;
  142. height: 36px;
  143. margin-bottom: 10px;
  144. }
  145. .login-tips {
  146. font-size: 12px;
  147. line-height: 30px;
  148. color: #fff;
  149. }
  150. </style>

总结

以上就是今天要讲的内容,本文仅仅简单介绍了登录页面的使用,未完待续。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家小花儿/article/detail/558418
推荐阅读