超详细的前后端实战项目(Spring系列加上vue3)前端篇(一)(一步步实现+ ...

打印 上一主题 下一主题

主题 1626|帖子 1626|积分 4878

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
最近想着一步步搭建一个前后端项目,将每一步详细的做出来。(如果有不足或者发起,也盼望大佬们指出哦)
前端初始化

1.根据vue脚手架创建vue项目

这里可以用很多方法创建vue项目,大家看着创建吧,只要能创建出来就可以了(用的vue3)







这里我加了router和vuex,emm,就不消ts了(感觉还是js用的更好一点)



OK,项目创建完毕,即可开始写前端代码了。

2.安装依赖:

        1.挑一个自己喜好的组件库引用一手,这里我选用arco design(也没必要只用Element-ui,可以试试其他的)
  1. npm install --save-dev @arco-design/web-vue
复制代码
OKOK,开始下载

安装好了之后,我们还要安装一些必要的依赖,好比axios,sass这些,emmmm,目前就安装这几个吧。
npm install axios
npm install sass -D

然后根据组件库官网的操作进行引入
  1. import { createApp } from 'vue'
  2. import ArcoVue from '@arco-design/web-vue';
  3. import App from './App.vue';
  4. import '@arco-design/web-vue/dist/arco.css';
  5. const app = createApp(App);
  6. app.use(ArcoVue);
  7. app.mount('#app');
复制代码
改造一下main.js中的代码
  1. import { createApp } from 'vue'
  2. import App from './App.vue'
  3. import router from './router'
  4. import store from './store'
  5. import ArcoVue from '@arco-design/web-vue';
  6. import '@arco-design/web-vue/dist/arco.css';
  7. createApp(App).use(store).use(ArcoVue).use(router).mount('#app')
复制代码
留意留意引入组件库之后,可以找个组件看看能不能使用该组件库,以防万一;
呐,这里我们就去官网看看

很好,就是你了,表单布局,我们点击其下方代码,将其放入App.vue试试能不能用

好嘞,随机找一串串代码放到App.vue中试试(不要试着从图片中照抄我的哈,自己去官网找一个试试Arco Design Vue)咱,主打一个快速。

嚯,出现了!那么组件库是能用哒!
好,第二步也就完成了。
这里我发起每做几步就开启调试一下。

3.调解目次,初始化项目:

        1.清空components(把HelloWorld.vue删了)
        2.新建目次api,utils,views
        3.把App.vue中用不到的代码都给删了,留一个  <router-view />就好了,然后,把router的index.js的代码全给解释了(emmm,直接删了感觉太贫苦,解释了背面写起来好做参照)
目前的目次结构就是如许了;
(App.vue就变成如许啦)


4.定义请求工具:

大家不要一开始写前端就直奔优美的”可跳转“页面,这边先整体规定一个向后端发请求的工具request.js
        在utils目次下创建request.js文件:
  1. import axios from 'axios';//导入axios
  2. //定义前缀
  3. const URL = 'http://localhost:8080';
  4. const instance = axios.create({URL})
  5. //来一个响应拦截器
  6. instance.interceptors.response.use(
  7.     result=>{
  8.         if(result.data.code == 0){
  9.             return result.data;
  10.         }
  11.         //如果不为0则表示失败
  12.         alert(result.data.message||'出现错误')
  13.         return Promise.reject(err);//异步的状态转化成失败的状态
  14.     },
  15.     err=>{
  16.         alert('服务异常');
  17.         return Promise.reject(err);//异步的状态转化成失败的状态
  18.     }
  19. )
  20. export default instance;
复制代码
表明一下这段代码:引入发请求的axios,然后定义一个开辟时期的请求必有前缀(这里直接写http://localhost:8080着实是有题目的,对于背面出现的跨域题目....emmmm,着实前端后端都有方式办理,看情况吧,背面再讲),做一个相应拦截器,对结果进行判断,然后导出
(这里需要提示一下统一相应有哪些(不然可能会不太好理解))
后端那一块统一相应数据:code:0表现乐成,1表现失败;msg: 提示信息;data:数据

前端代码编写开始!!

OK啊各位,初始化完成我们便要开始编写代码了。
首先,我们先明白一波步骤:
        确定布局  --> 添补各部分代码 -->  后端插入

(如果涉及与后端的交互,遵照以下步骤
        1.搭建页面(html,css)-> 2.绑定数据与事件 -> 3.调用后端接口)


好嘞,认识了吗各位,不熟练也没事,我们先找一个练练手。
先从组件库这里找到布局:


这布局,看似普通,实则帅的雅痞,就它了。引入代码
回到目次component下,创建一个新的文件GlobalPage.vue
(众所周知的小技巧:<vue>可快速构建vue文件)
  1. <template>
  2.    <a-layout style="height: 400px;">
  3.       <a-layout-header>Header</a-layout-header>
  4.       <a-layout>
  5.         <a-layout-sider theme="dark">Sider</a-layout-sider>
  6.         <a-layout-content>Content</a-layout-content>
  7.       </a-layout>
  8.       <a-layout-footer>Footer</a-layout-footer>
  9.     </a-layout>
  10. </template>
  11. <script>
  12. export default {
  13. }
  14. </script>
  15. <style scoped>
  16. .layout-demo :deep(.arco-layout-header),
  17. .layout-demo :deep(.arco-layout-footer),
  18. .layout-demo :deep(.arco-layout-sider-children),
  19. .layout-demo :deep(.arco-layout-content) {
  20.   display: flex;
  21.   flex-direction: column;
  22.   justify-content: center;
  23.   color: var(--color-white);
  24.   font-size: 16px;
  25.   font-stretch: condensed;
  26.   text-align: center;
  27. }
  28. .layout-demo :deep(.arco-layout-header),
  29. .layout-demo :deep(.arco-layout-footer) {
  30.   height: 64px;
  31.   background-color: var(--color-primary-light-4);
  32. }
  33. .layout-demo :deep(.arco-layout-sider) {
  34.   width: 206px;
  35.   background-color: var(--color-primary-light-3);
  36. }
  37. .layout-demo :deep(.arco-layout-content) {
  38.   background-color: rgb(var(--arcoblue-6));
  39. }
  40. </style>
复制代码
然后我们改一下index.js文件(将GlobalPage引入)(要是看着那些注解感觉不美观的话就直接删了)
  1. import { createRouter, createWebHashHistory } from 'vue-router'
  2. import MainPage from '../components/GlobalPage.vue'
  3. const routes = [
  4.   // {
  5.   //   path: '/',
  6.   //   name: 'home',
  7.   //   component: HomeView
  8.   // },
  9.   // {
  10.   //   path: '/about',
  11.   //   name: 'about',
  12.   //   // route level code-splitting
  13.   //   // this generates a separate chunk (about.[hash].js) for this route
  14.   //   // which is lazy-loaded when the route is visited.
  15.   //   component: () => import(/* webpackChunkName: "about" */ '../views/AboutView.vue')
  16.   // }
  17.   {
  18.     path: '/',
  19.     name: 'mainPage',
  20.     component: MainPage
  21.   }
  22. ]
  23. const router = createRouter({
  24.   history: createWebHashHistory(),
  25.   routes
  26. })
  27. export default router
复制代码
运行一手看看(记得每次有一些大改就要看看情况,改多再看就会很贫苦,bug也不好排查)
运行出来就是这么个界面

搭建Header和Footer代码

先把头部和尾部的代码办理了。
先来尾部吧,我觉得这个比较简朴(哈)
一样平常来说,网站的底部都是一些网站运营的介绍什么的(大多都是哈,也不一定全是)

这里我就以大家都爱的4399为例(大多都是哈,也不一定全是,哈哈哈)
emmm,这里我们可以把Footer这一块封装为一个组件,因为固然定义的GlobalPage属于是全局的页面,但万一之后会跳转到其他的页面呢,这里我觉得封装成组件更好一些(看起来也更轻巧一些)
在views目次下创建GlobalFooter.vue
  1. <template>
  2.   <div id="header">由Heath ceTide 创作的网站 XXX 有限公司</div>
  3. </template>
  4. <script>
  5. export default {};
  6. </script>
  7. <style>
  8. #header {
  9.   font-family: "Satisfy", cursive;
  10.   font-size: 16px;
  11.   color: rgb(102, 149, 164);
  12.   margin-right: 20px;
  13. }
  14. </style>
复制代码
差不多了,将其更换掉GlobalPage的header
  1. <template>
  2.    <a-layout style="height: 400px;">
  3.       <a-layout-header>Header</a-layout-header>
  4.       <a-layout>
  5.         <a-layout-sider theme="dark">Sider</a-layout-sider>
  6.         <a-layout-content>Content</a-layout-content>
  7.       </a-layout>
  8.       <a-layout-footer>
  9.         <global-footer></global-footer>
  10.       </a-layout-footer>
  11.     </a-layout>
  12. </template>
  13. <script>
  14. import GlobalFooter from '../views/GlobalFooter.vue'
  15. export default {
  16.   components: { GlobalFooter },
  17. }
  18. </script>
复制代码

展示出了样式就行了,(之后可以美化以下),好,然后我们开始整Header,
这一块导航栏,我觉得吧,还是用组件比较合适(倒不是不会整,究竟也贫苦,不消自己手敲的绝不自己手敲代码)

就选这个深色模式导航啦,新建GlobalHeader.vue文件把代码用CV大法放进去
  1. <template>
  2.   <div class="menu-demo">
  3.     <a-menu mode="horizontal" theme="dark" :default-selected-keys="['1']">
  4.       <a-menu-item key="0" :style="{ padding: 0, marginRight: '38px' }" disabled>
  5.         <div
  6.           :style="{
  7.             width: '80px',
  8.             height: '30px',
  9.             background: 'var(--color-fill-3)',
  10.             cursor: 'text',
  11.           }"
  12.         />
  13.       </a-menu-item>
  14.       <a-menu-item key="1">Home</a-menu-item>
  15.       <a-menu-item key="2">Solution</a-menu-item>
  16.       <a-menu-item key="3">Cloud Service</a-menu-item>
  17.       <a-menu-item key="4">Cooperation</a-menu-item>
  18.     </a-menu>
  19.   </div>
  20. </template>
  21. <style scoped>
  22. .menu-demo {
  23.   box-sizing: border-box;
  24.   width: 100%;
  25.   background-color: var(--color-neutral-2);
  26. }
  27. </style>
复制代码
  1. <template>
  2.   <a-layout style="height: 400px">
  3.     <a-layout-header><global-header></global-header></a-layout-header>
  4.     <a-layout>
  5.       <a-layout-sider theme="dark">Sider</a-layout-sider>
  6.       <a-layout-content>Content</a-layout-content>
  7.     </a-layout>
  8.     <a-layout-footer>
  9.       <global-footer class="footer"></global-footer>
  10.     </a-layout-footer>
  11.   </a-layout>
  12. </template>
  13. <script>
  14. import GlobalFooter from "../views/GlobalFooter.vue";
  15. import GlobalHeader from "../views/GlobalHeader.vue";
  16. export default {
  17.   components: { GlobalFooter, GlobalHeader },
  18. };
  19. </script>
  20. <style scoped>
  21. .layout-demo :deep(.arco-layout-header),
  22. .layout-demo :deep(.arco-layout-footer),
  23. .layout-demo :deep(.arco-layout-sider-children),
  24. .layout-demo :deep(.arco-layout-content) {
  25.   display: flex;
  26.   flex-direction: column;
  27.   justify-content: center;
  28.   color: var(--color-white);
  29.   font-size: 16px;
  30.   font-stretch: condensed;
  31.   text-align: center;
  32. }
  33. .layout-demo :deep(.arco-layout-header),
  34. .layout-demo :deep(.arco-layout-footer) {
  35.   height: 64px;
  36.   background-color: var(--color-primary-light-4);
  37. }
  38. .layout-demo :deep(.arco-layout-sider) {
  39.   width: 206px;
  40.   background-color: var(--color-primary-light-3);
  41. }
  42. .layout-demo :deep(.arco-layout-content) {
  43.   background-color: rgb(var(--arcoblue-6));
  44. }
  45. .footer {
  46.   background-color: aliceblue;
  47.   padding: 16px;
  48.   position: sticky;
  49.   bottom: 0;
  50.   left: 0;
  51.   right: 0;
  52.   text-align: center;
  53.   letter-spacing: 3px;
  54. }
  55. </style>
复制代码

着实这个空的区域可以加一个logo或者其他什么的

呐,就像如许
OK,目前的页面就是这个样子了;

搭建搜索页面

好的,下面整一个全局的搜索框页面吧
创建一个SearchPage.vue 文件
从组件库中找到一个合适的搜索框

  1. <!--SearchPage.vue代码-->
  2. <template>
  3.   <a-space direction="vertical" size="large">
  4.     <a-input-search
  5.       :style="{ width: '320px' }"
  6.       placeholder="Please enter something"
  7.       button-text="Search"
  8.       search-button
  9.     />
  10.   </a-space>
  11. </template>
  12. <script>
  13. export default {};
  14. </script>
  15. <style>
  16. </style>
复制代码
将新组件放到GlobalPage中(临时的,之后还是要处理路由的)
  1. <template>
  2.   <a-layout style="height: 400px">
  3.     <a-layout-header><global-header></global-header></a-layout-header>
  4.     <a-layout>
  5.       <a-layout-sider theme="dark">Sider</a-layout-sider>
  6.       <a-layout-content><search-page></search-page></a-layout-content>
  7.     </a-layout>
  8.     <a-layout-footer>
  9.       <global-footer class="footer"></global-footer>
  10.     </a-layout-footer>
  11.   </a-layout>
  12. </template>
  13. <script>
  14. import GlobalFooter from "../views/GlobalFooter.vue";
  15. import GlobalHeader from "../views/GlobalHeader.vue";
  16. import SearchPage from '../views/SearchPage.vue';
  17. export default {
  18.   components: { GlobalFooter, GlobalHeader, SearchPage },
  19. };
  20. </script>
复制代码

如今搜索框就出来了,(这里最右边加了一点点小细节(不紧张)之后会把代码发出来)
这里着实可以加一个搜索框等候结果
  1. <template>
  2.   <div id="search">
  3.     <a-space direction="vertical" size="large">
  4.       <a-input-search
  5.         :style="{ width: '320px' }"
  6.         placeholder="Please enter something"
  7.         button-text="Search"
  8.         search-button
  9.       />
  10.     </a-space>
  11.     <a-space direction="vertical" size="large">
  12.       <a-input-search
  13.         :style="{ width: '320px' }"
  14.         placeholder="Please enter something"
  15.         button-text="Search"
  16.         search-button
  17.         loading
  18.       />
  19.     </a-space>
  20.   </div>
  21. </template>
  22. <script>
  23. export default {};
  24. </script>
  25. <style>
  26. </style>
复制代码
这里着实是复制了两个搜索框代码,不外别的一个加上了loading属性,如许就能表现出等候中的结果

呐呐呐,就是如许,然后我们再用v-if定义一下它的表现和隐蔽就可以了
ok,演示一下:
先设置script 为setup,然后引入ref
  1. <script setup>
  2. import {ref} from 'vue';
复制代码
 还记得之前说的三部曲吗: 1.搭建页面(html,css)-> 2.绑定数据与实践 -> 3.调用后端接口)
那我们以及写好了搜索框了,也该进行数据绑定了(这里临时不进行后端接口调用,(究竟还没开辟))
对于一个组件的表现和隐蔽我们直接写
  1. <script setup>
  2. import {ref} from 'vue';const isSearch = ref(false)
复制代码
然后呢,两个搜索框绑定该属性(一个是isSearch,一个是!isSearch),如许就能保持一个表现,一个隐蔽了。那么,怎样实现转换呢,平时在搜索的时间,当我们点击了搜索按钮的时间就会出现转换结果,如果网比较好的话,估计也就直接跳转了,(如果网不好的话,搜索框转圈转了一会儿就会恢复原样)
那么,我们定义一个函数,在正常情况下点击搜索的时间触发,转换为搜索中的样式,然后过几秒就恢复原状。
那么开始定义吧;
  1. <script setup>
  2. import {ref} from 'vue';const isSearch = ref(false)const onSearch = () => {  isSearch.value = true;  setTimeout(() => {    isSearch.value = false;  }, 5000);};</script>
复制代码
这里定义了一个函数,点击之后,isSearch改变,比及五秒之后,值恢复。来试试吧
  1. <template>  <div id="search">    <a-space direction="vertical" size="large" v-if="!isSearch">      <a-input-search        :style="{ width: '320px' }"        placeholder="Please enter something"        button-text="Search"        search-button        @click=onSearch      />    </a-space>    <a-space direction="vertical" size="large" v-if="isSearch">      <a-input-search        :style="{ width: '320px' }"        placeholder="Please enter something"        button-text="Search"        search-button        loading      />    </a-space>  </div></template><script setup>
  2. import {ref} from 'vue';const isSearch = ref(false)const onSearch = () => {  isSearch.value = true;  setTimeout(() => {    isSearch.value = false;  }, 5000);};</script>
复制代码

乐成了,那再来美满一下
有搜索框,固然要有表现搜索内容的区域,
再去组件库看看有没有什么合适的

就用这个吧,
  1. <template>
  2.   <div id="searchPage">
  3.    
  4.     <div class="search">
  5.       <a-space direction="vertical" size="large" v-if="!isSearch">
  6.         <a-input-search
  7.           :style="{ width: '620px' }"
  8.           placeholder="Please enter something"
  9.           button-text="Search"
  10.           search-button
  11.           @click="onSearch"
  12.         />
  13.       </a-space>
  14.       <a-space direction="vertical" size="large" v-if="isSearch">
  15.         <a-input-search
  16.           :style="{ width: '620px' }"
  17.           placeholder="Please enter something"
  18.           button-text="Search"
  19.           search-button
  20.           loading
  21.         />
  22.       </a-space>
  23.     </div>
  24.     <a-space direction="vertical" size="large">
  25.       <a-radio-group v-model="type" type="button">
  26.         <a-radio value="line">Line</a-radio>
  27.         <a-radio value="card">Card</a-radio>
  28.         <a-radio value="card-gutter">Card Gutter</a-radio>
  29.         <a-radio value="text">Text</a-radio>
  30.         <a-radio value="rounded">Rounded</a-radio>
  31.         <a-radio value="capsule">Capsule</a-radio>
  32.       </a-radio-group>
  33.       <a-radio-group v-model="size" type="button">
  34.         <a-radio value="mini">Mini</a-radio>
  35.         <a-radio value="small">Small</a-radio>
  36.         <a-radio value="medium">Medium</a-radio>
  37.         <a-radio value="large">Large</a-radio>
  38.       </a-radio-group>
  39.       <a-tabs :type="type" :size="size">
  40.         <a-tab-pane key="1" title="Tab 1"> Content of Tab Panel 1 </a-tab-pane>
  41.         <a-tab-pane key="2" title="Tab 2"> Content of Tab Panel 2 </a-tab-pane>
  42.         <a-tab-pane key="3" title="Tab 3"> Content of Tab Panel 3 </a-tab-pane>
  43.       </a-tabs>
  44.     </a-space>
  45.   </div>
  46. </template>
  47. <script setup>
  48. import { ref } from "vue";
  49. const isSearch = ref(false);
  50. const onSearch = () => {
  51.   isSearch.value = true;
  52.   setTimeout(() => {
  53.     isSearch.value = false;
  54.   }, 5000);
  55. };
  56. </script>
  57. <style scoped>
  58. .search{
  59.     margin: 30px auto;
  60. }
  61. </style>
复制代码
添加代码并做一些优化

目前就是这个样子了。
emmm,感觉不太对,好像有点快了,要不还是做一个登录注册页面吧。。。

搭建登录注册页面

创建LoginPage.vue
这一块我觉得还挺容易的,先给个示例代码吧
  1. <template>
  2.   <div class="container">
  3.     <div class="login-box">
  4.       <!-- Login Form -->
  5.       <form action="">
  6.         <h2>Login</h2>
  7.         <div class="input-box">
  8.           <span class="icon"><i class="fa-solid fa-envelope"></i></span>
  9.           <input type="email" required placeholder="Email" />
  10.         </div>
  11.         <div class="input-box">
  12.           <span class="icon"><i class="fa-solid fa-lock"></i></span>
  13.           <input type="password" placeholder="Password" required />
  14.         </div>
  15.         <div class="remember-forget">
  16.           <label><input type="checkbox" />Remember Me</label>
  17.           <a href="#">Forgot Password?</a>
  18.         </div>
  19.         <button type="submit">Login</button>
  20.         <div class="register-link">
  21.           <a href="#">Don't have an account? Create Now!</a>
  22.         </div>
  23.       </form>
  24.     </div>
  25.   </div>
  26. </template>
  27. <script>
  28. export default {
  29. }
  30. </script>
  31. <style scoped>
  32. * {
  33.   margin: 0;
  34.   padding: 0;
  35.   box-sizing: border-box;
  36.   font-family: "Poppins", sans-serif;
  37. }
  38. .container {
  39.   width: 100%;
  40.   height: 100vh;
  41.   background: url("../assets/background.jpg") no-repeat;
  42.   background-size: cover;
  43.   background-position: center;
  44.   display: flex;
  45.   justify-content: center;
  46.   align-items: center;
  47. }
  48. .container .login-box {
  49.   position: relative;
  50.   width: 390px;
  51.   height: 420px;
  52.   background-color: transparent;
  53.   border: 2px solid rgba(255, 255, 255, 0.5);
  54.   border-radius: 20px;
  55.   display: flex;
  56.   justify-content: center;
  57.   align-items: center;
  58.   backdrop-filter: blur(15px);
  59. }
  60. .login-box h2 {
  61.   font-size: 28px;
  62.   color: #fff;
  63.   text-align: center;
  64. }
  65. .login-box .input-box {
  66.   position: relative;
  67.   width: 310px;
  68.   margin: 30px 0;
  69.   border-bottom: 2px solid #fff;
  70. }
  71. .input-box input {
  72.   width: 100%;
  73.   height: 50px;
  74.   background: transparent;
  75.   border: none;
  76.   outline: none;
  77.   font-size: 16px;
  78.   color: #fff;
  79.   padding: 0 35px 0 5px;
  80. }
  81. .input-box input::placeholder {
  82.   color: #f9f9f9;
  83. }
  84. .input-box .icon {
  85.   position: absolute;
  86.   right: 8px;
  87.   color: #fff;
  88.   font-size: 18px;
  89.   line-height: 50px;
  90. }
  91. .login-box .remember-forget {
  92.   margin: -15px 0 15px;
  93.   font-size: 15px;
  94.   color: #fff;
  95.   display: flex;
  96.   justify-content: space-between;
  97. }
  98. .remember-forget label input {
  99.   margin-right: 3px;
  100. }
  101. .login-box button {
  102.   width: 100%;
  103.   height: 40px;
  104.   background: #fff;
  105.   border: none;
  106.   outline: none;
  107.   border-radius: 40px;
  108.   cursor: pointer;
  109.   font-size: 16px;
  110.   color: #000;
  111.   transition: all 0.5s;
  112. }
  113. .login-box button:hover {
  114.   background: #1f73c9;
  115.   color: #fff;
  116. }
  117. .login-box .register-link {
  118.   font-size: 15px;
  119.   color: #fff;
  120.   text-align: center;
  121.   margin: 20px 0 10px;
  122. }
  123. .remember-forget a,
  124. .register-link a {
  125.   color: #fff;
  126.   text-decoration: none;
  127. }
  128. .remember-forget a:hover,
  129. .register-link a:hover {
  130.   text-decoration: underline;
  131. }
  132. /* Responsive Design */
  133. @media (max-width: 460px) {
  134.   .container .login-box {
  135.     width: 350px;
  136.   }
  137.   .login-box .input-box {
  138.     width: 290px;
  139.   }
  140. }
  141. @media (max-width: 360px) {
  142.   .container .login-box {
  143.     width: 100%;
  144.     height: 100vh;
  145.     border: none;
  146.   }
  147. }
  148. </style>
复制代码
这一块代码是之前找到的一个登录页代码,我觉着就还挺好

不外吧,我决定还是不消这个代码,去组件库上找找吧(主要还是要加深一下组件库的使用)
好了就用这个

小改一下吧;
  1. <template>
  2.   <div class="container">
  3.     <div class="login-box">
  4.       <a-form
  5.         :model="form"
  6.         :style="{ width: '600px' }"
  7.         @submit="handleSubmit"
  8.         class="input-box"
  9.       >
  10.         <h2 style="margin-bottom: 60px">Login</h2>
  11.         <a-form-item
  12.           field="name"
  13.           tooltip="Please enter username"
  14.           label="账号"
  15.           class="element"
  16.         >
  17.           <a-input
  18.             v-model="form.name"
  19.             placeholder="please enter your username..."
  20.             style="margin-right: 40px"
  21.           />
  22.         </a-form-item>
  23.         <a-form-item field="post" label="密码" class="element">
  24.           <a-input
  25.             v-model="form.post"
  26.             placeholder="please enter your password..."
  27.             style="margin-right: 40px"
  28.           />
  29.         </a-form-item>
  30.         <a-form-item field="isRead">
  31.           <a-checkbox v-model="form.isRead">
  32.             I have read the manual
  33.           </a-checkbox>
  34.         </a-form-item>
  35.         <a-form-item>
  36.           <a-button html-type="submit" class="input-box">Submit</a-button>
  37.         </a-form-item>
  38.         <div class="register-link">
  39.           <a href="#">Don't have an account? Create Now!</a>
  40.         </div>
  41.       </a-form>
  42.     </div>
  43.   </div>
  44. </template>
  45. <script>
  46. </script>
  47. <style scoped>
  48. * {
  49.   margin: 0;
  50.   padding: 0;
  51.   box-sizing: border-box;
  52.   font-family: "Poppins", sans-serif;
  53.   display: flex;
  54.   justify-content: center;
  55. }
  56. .container {
  57.   width: 100%;
  58.   height: 100vh;
  59.   background: url("../assets/background.jpg") no-repeat;
  60.   background-size: cover;
  61.   background-position: center;
  62.   display: flex;
  63.   justify-content: center;
  64.   align-items: center;
  65. }
  66. .container .login-box {
  67.   position: relative;
  68.   width: 500px;
  69.   height: 580px;
  70.   background-color: transparent;
  71.   border: 2px solid rgba(255, 255, 255, 0.5);
  72.   border-radius: 20px;
  73.   display: flex;
  74.   justify-content: center;
  75.   align-items: center;
  76.   backdrop-filter: blur(15px);
  77. }
  78. .login-box h2 {
  79.   font-size: 28px;
  80.   color: #fff;
  81.   text-align: center;
  82. }
  83. .login-box .input-box {
  84.   position: relative;
  85.   width: 310px;
  86.   margin: 30px 0;
  87. }
  88. .input-box input {
  89.   width: 80%;
  90.   height: 60px;
  91.   background: transparent;
  92.   border: none;
  93.   outline: none;
  94.   font-size: 16px;
  95.   color: #fff;
  96.   padding: 0 2px 0 5px;
  97. }
  98. .input-box input::placeholder {
  99.   color: #f9f9f9;
  100. }
  101. .input-box .icon {
  102.   position: absolute;
  103.   right: 8px;
  104.   color: #fff;
  105.   font-size: 16px;
  106.   line-height: 25px;
  107. }
  108. .login-box .remember-forget {
  109.   margin: -15px 0 15px;
  110.   font-size: 15px;
  111.   color: #fff;
  112.   display: flex;
  113.   justify-content: space-between;
  114. }
  115. .remember-forget label input {
  116.   margin-right: 30px;
  117. }
  118. .login-box button {
  119.   width: 100%;
  120.   height: 40px;
  121.   background: #fff;
  122.   border: none;
  123.   outline: none;
  124.   border-radius: 40px;
  125.   cursor: pointer;
  126.   font-size: 16px;
  127.   color: #000;
  128.   transition: all 0.5s;
  129. }
  130. .login-box button:hover {
  131.   background: #1f73c9;
  132.   color: #fff;
  133. }
  134. .login-box .register-link {
  135.   font-size: 15px;
  136.   color: #fff;
  137.   text-align: center;
  138.   margin: 5px 0 5px;
  139. }
  140. .remember-forget a,
  141. .register-link a {
  142.   color: #fff;
  143.   text-decoration: none;
  144. }
  145. .remember-forget a:hover,
  146. .register-link a:hover {
  147.   text-decoration: underline;
  148. }
  149. /* Responsive Design */
  150. @media (max-width: 460px) {
  151.   .container .login-box {
  152.     width: 350px;
  153.   }
  154.   .login-box .input-box {
  155.     width: 290px;
  156.   }
  157. }
  158. @media (max-width: 360px) {
  159.   .container .login-box {
  160.     width: 100%;
  161.     height: 100vh;
  162.     border: none;
  163.   }
  164. }
  165. .element {
  166.   margin: 20px 0;
  167. }
  168. </style>
复制代码
emmm,这代码可谓一坨(发出来也需要些勇气啊。。)
大家如果有自己的写的规范代码就用自己的(hhh)
那么,我们开始前面的三部曲:搭建页面以及完成,可以开始绑定数据与事件了。
  1. <script setup>
  2. import {ref} from 'vue';const loginData = ref({    username: '',    password: '',    isRead: false,})
复制代码
先引入ref,然后创建loginData,然后v-model绑定数据
  1. <template>  <div class="container">    <div class="login-box">      <a-form        :model="loginData"        :style="{ width: '600px' }"        @submit="handleSubmit"        class="input-box"      >        <h2 style="margin-bottom: 60px">Login</h2>        <a-form-item          field="name"          tooltip="Please enter username"          label="账号"          class="element"          :rules= "rules"        >          <a-input            v-model="loginData.username"            placeholder="please enter your username..."            style="margin-right: 40px"          />        </a-form-item>        <a-form-item field="post" label="密码" class="element" :rules= "rules">          <a-input            v-model="loginData.password"            placeholder="please enter your password..."            style="margin-right: 40px"          />        </a-form-item>        <a-form-item field="isRead">          <a-checkbox v-model="loginData.isRead">            I have read the manual          </a-checkbox>        </a-form-item>        <a-form-item>          <a-button html-type="submit" class="input-box">Submit</a-button>        </a-form-item>        <div class="register-link">          <a href="#">Don't have an account? Create Now!</a>        </div>      </a-form>    </div>  </div></template><script setup>
  2. import {ref} from 'vue';const loginData = ref({    username: '',    password: '',    isRead: false,})const rules = [{      validator: (value, cb) => {        return new Promise(resolve => {          window.setTimeout(() => {            if (value !== ' ') {              cb('content not empty')            }            resolve()          }, 1000)        })      }    }];</script><style scoped>* {  margin: 0;  padding: 0;  box-sizing: border-box;  font-family: "Poppins", sans-serif;  display: flex;  justify-content: center;}.container {  width: 100%;  height: 100vh;  background: url("../assets/background.jpg") no-repeat;  background-size: cover;  background-position: center;  display: flex;  justify-content: center;  align-items: center;}.container .login-box {  position: relative;  width: 500px;  height: 580px;  background-color: transparent;  border: 2px solid rgba(255, 255, 255, 0.5);  border-radius: 20px;  display: flex;  justify-content: center;  align-items: center;  backdrop-filter: blur(15px);}.login-box h2 {  font-size: 28px;  color: #fff;  text-align: center;}.login-box .input-box {  position: relative;  width: 310px;  margin: 30px 0;}.input-box input {  width: 80%;  height: 60px;  background: transparent;  border: none;  outline: none;  font-size: 16px;  color: #fff;  padding: 0 2px 0 5px;}.input-box input::placeholder {  color: #f9f9f9;}.input-box .icon {  position: absolute;  right: 8px;  color: #fff;  font-size: 16px;  line-height: 25px;}.login-box .remember-forget {  margin: -15px 0 15px;  font-size: 15px;  color: #fff;  display: flex;  justify-content: space-between;}.remember-forget label input {  margin-right: 30px;}.login-box button {  width: 100%;  height: 40px;  background: #fff;  border: none;  outline: none;  border-radius: 40px;  cursor: pointer;  font-size: 16px;  color: #000;  transition: all 0.5s;}.login-box button:hover {  background: #1f73c9;  color: #fff;}.login-box .register-link {  font-size: 15px;  color: #fff;  text-align: center;  margin: 5px 0 5px;}.remember-forget a,.register-link a {  color: #fff;  text-decoration: none;}.remember-forget a:hover,.register-link a:hover {  text-decoration: underline;}/* Responsive Design */@media (max-width: 460px) {  .container .login-box {    width: 350px;  }  .login-box .input-box {    width: 290px;  }}@media (max-width: 360px) {  .container .login-box {    width: 100%;    height: 100vh;    border: none;  }}.element {  margin: 20px 0;}</style>
复制代码
这里可以添加一个校验规则,
在组件库这里找一下表单的校验规则
  1. <script setup>
  2. import {ref} from 'vue';const loginData = ref({    username: '',    password: '',    isRead: false,})const rules = [{      validator: (value, cb) => {        return new Promise(resolve => {          window.setTimeout(() => {            if (value === ' ') {              cb('content not empty')            }            resolve()          }, 1000)        })      }    }];</script>
复制代码
任意定义了一个,大家可以自己定义看看,(emmm,这里我感觉element-ui的校验规则更好一丢丢)。
好了,既然定义好了登录界面,就可以试试向后端发起请求了。
这里开始在api文件夹下面创建一个文件user.js然后编写一个登录接口函数

  1. import request from '../utils/request'
  2. //创建一个调用登录接口函数
  3. export const userLoginService = (loginData) =>{
  4.     //用urlSearchParams完成传递
  5.     const params = new URLSearchParams()
  6.     for(let key in loginData){
  7.         params.append(key,loginData[key]);
  8.     }
  9.     return request.post('/user/login',params);
  10. }
复制代码
定义之后就去登录页调用
  1.         <a-form-item>
  2.           <a-button html-type="submit" class="input-box" @click="login"
  3.             >Submit</a-button
  4.           >
  5.         </a-form-item>
复制代码
在submit提交这里加上@click="login"
然后定义方法:(获取信息,如果msg提示信息不为0,则表现消息,为0就表现登岸乐成)
  1. const login = async()=>{
  2.     let result = await userLoginService(loginData.value);
  3.     alert(result.msg?result.msg:'登录成功');
  4. }
复制代码
不外,这里用欣赏器默认的alert感觉不太美观啊,究竟都用组件库了,

消息类型:就决定是你了!
引入一手修改代码,
  1. <script setup>
  2. import { h } from 'vue';
  3. import { IconExclamationCircleFill } from '@arco-design/web-vue/es/icon';
  4. import { ref } from "vue";
  5. import {userLoginService} from '../api/user'
  6. const loginData = ref({
  7.   username: "",
  8.   password: "",
  9.   isRead: false,
  10. });
  11. const rules = [
  12.   {
  13.     validator: (value, cb) => {
  14.       return new Promise((resolve) => {
  15.         window.setTimeout(() => {
  16.           if (value !== " ") {
  17.             cb("content not empty");
  18.           }
  19.           resolve();
  20.         }, 1000);
  21.       });
  22.     },
  23.   },
  24. ];
  25. const renderIcon = () => h(IconExclamationCircleFill);
  26. const login = async()=>{
  27.     let result = await userLoginService(loginData.value);
  28.     renderIcon(result.msg?result.msg:'登录成功');
  29. }
  30. </script>
复制代码

好,感觉如许也就差不多了,下面展示一下登录页代码
  1. <template>  <div class="container">    <div class="login-box">      <a-form        :model="loginData"        :style="{ width: '600px' }"        @submit="handleSubmit"        class="input-box"      >        <h2 style="margin-bottom: 60px">Login</h2>        <a-form-item          field="name"          tooltip="Please enter username"          label="账号"          class="element"          :rules="rules"        >          <a-input            v-model="loginData.username"            placeholder="please enter your username..."            style="margin-right: 40px"          />        </a-form-item>        <a-form-item field="post" label="密码" class="element" :rules="rules">          <a-input            v-model="loginData.password"            placeholder="please enter your password..."            style="margin-right: 40px"          />        </a-form-item>        <a-form-item field="isRead">          <a-checkbox v-model="loginData.isRead">            I have read the manual          </a-checkbox>        </a-form-item>        <a-form-item>
  2.           <a-button html-type="submit" class="input-box" @click="login"
  3.             >Submit</a-button
  4.           >
  5.         </a-form-item>        <div class="register-link">          <a href="#">Don't have an account? Create Now!</a>        </div>      </a-form>    </div>  </div></template><script setup>
  6. import { h } from 'vue';
  7. import { IconExclamationCircleFill } from '@arco-design/web-vue/es/icon';
  8. import { ref } from "vue";
  9. import {userLoginService} from '../api/user'
  10. const loginData = ref({
  11.   username: "",
  12.   password: "",
  13.   isRead: false,
  14. });
  15. const rules = [
  16.   {
  17.     validator: (value, cb) => {
  18.       return new Promise((resolve) => {
  19.         window.setTimeout(() => {
  20.           if (value !== " ") {
  21.             cb("content not empty");
  22.           }
  23.           resolve();
  24.         }, 1000);
  25.       });
  26.     },
  27.   },
  28. ];
  29. const renderIcon = () => h(IconExclamationCircleFill);
  30. const login = async()=>{
  31.     let result = await userLoginService(loginData.value);
  32.     renderIcon(result.msg?result.msg:'登录成功');
  33. }
  34. </script><style scoped>* {  margin: 0;  padding: 0;  box-sizing: border-box;  font-family: "Poppins", sans-serif;  display: flex;  justify-content: center;}.container {  width: 100%;  height: 100vh;  background: url("../assets/background.jpg") no-repeat;  background-size: cover;  background-position: center;  display: flex;  justify-content: center;  align-items: center;}.container .login-box {  position: relative;  width: 500px;  height: 580px;  background-color: transparent;  border: 2px solid rgba(255, 255, 255, 0.5);  border-radius: 20px;  display: flex;  justify-content: center;  align-items: center;  backdrop-filter: blur(15px);}.login-box h2 {  font-size: 28px;  color: #fff;  text-align: center;}.login-box .input-box {  position: relative;  width: 310px;  margin: 30px 0;}.input-box input {  width: 80%;  height: 60px;  background: transparent;  border: none;  outline: none;  font-size: 16px;  color: #fff;  padding: 0 2px 0 5px;}.input-box input::placeholder {  color: #f9f9f9;}.input-box .icon {  position: absolute;  right: 8px;  color: #fff;  font-size: 16px;  line-height: 25px;}.login-box .remember-forget {  margin: -15px 0 15px;  font-size: 15px;  color: #fff;  display: flex;  justify-content: space-between;}.remember-forget label input {  margin-right: 30px;}.login-box button {  width: 100%;  height: 40px;  background: #fff;  border: none;  outline: none;  border-radius: 40px;  cursor: pointer;  font-size: 16px;  color: #000;  transition: all 0.5s;}.login-box button:hover {  background: #1f73c9;  color: #fff;}.login-box .register-link {  font-size: 15px;  color: #fff;  text-align: center;  margin: 5px 0 5px;}.remember-forget a,.register-link a {  color: #fff;  text-decoration: none;}.remember-forget a:hover,.register-link a:hover {  text-decoration: underline;}/* Responsive Design */@media (max-width: 460px) {  .container .login-box {    width: 350px;  }  .login-box .input-box {    width: 290px;  }}@media (max-width: 360px) {  .container .login-box {    width: 100%;    height: 100vh;    border: none;  }}.element {  margin: 20px 0;}</style>
复制代码
好了,本日的前端就忙碌到这里吧(下一篇文章再见)。
总结一下:1.完成了前端初始化4步,2.完成了全局页面的布局,3.完成了搜索页的代码,和登录页的代码。


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

反转基因福娃

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表