当前位置: 首页 > news >正文

开始尝试从0写一个项目--前端(一)

基础项目构建

创建VUE初始工程

确保自己下载了node.js和npm

node -v     //查看node.js的版本
npm -v      //查看npm的版本
npm i @vue/cli -g    //安装VUE CLI

创建

以管理员身份运行

输入:vue ui

就会进入

点击创建

自定义项目名字,选择npm管理

结构

用vscode打开这个项目

运行

打开终端

快捷键:ctrl+j

输入npm run serve回车

然后进入给的网址

修改端口

vue.config.js

const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({transpileDependencies: true,devServer: {port: 8181}
})

现在我们就是在这个界面开始编写我们的代码

2024.7.4


学生登录界面

参考这篇文章

Vue 实现登录注册功能(前后端分离完整案例) | 软件研会

参考文章中遇到的一些问题

问题:解决error: Component name “xxx” should always be multi-word.

解决:

解决error: Component name “xxx” should always be multi-word._error component name "about" should always be mult-CSDN博客

问题:import VueAxios from 'vue-axios'中vue-axios找不到报错

解决:

npm i vue-axios

问题:点击登录之后,一直网页报错

解决措施:(麻了,我各种翻阅资料,居然是这里出错了,气死了!!!!!!!花费了我2小时)

src\views\login\Login.vue

问题基本搞定,还有一些小细节:

我们不需要注册这个版本,所以我没有搞。

基本就ok了

所有的代码:

src\App.vue


<template><div id="app"><router-view/></div>
</template><script>export default {name: 'App',components: {}
}
</script><style>
#app {font-family: Avenir, Helvetica, Arial, sans-serif;-webkit-font-smoothing: antialiased;-moz-osx-font-smoothing: grayscale;text-align: center;color: #2c3e50;
}
</style>

src\main.js

import Vue from 'vue'
import App from './App.vue'
import store from './store'import router from './router'      //路由 2
import VueRouter from 'vue-router' // 路由 1import ElementUI from 'element-ui';	// Element 1
import 'element-ui/lib/theme-chalk/index.css'; // Element 2import axios from 'axios'  
import VueAxios from 'vue-axios'// 关闭 Vue 的生产提示
Vue.config.productionTip = false// 使用插件
Vue.use(ElementUI); // Element 3
Vue.use(VueRouter) // 路由 3
Vue.use(VueAxios, axios) // 使用 axios 插件// 创建 Vue 实例对象
new Vue({router,store,render: h => h(App)
}).$mount('#app')

vue.config.js

const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({transpileDependencies: true,lintOnSave: false,devServer: {port: 8181,// 代理服务器可以将路由中的指定前缀转发到指定的后端服务器中proxy: {'/api': {target: 'http://localhost:8080',ws: true, // 是否启用websocketschangeOrigin: true,  // 代理时是否更改hostpathRewrite: {'^/api': '' //这里理解成用'/api'代替target里面的地址}}}}
})

src\views\login\Login.vue

<template><div><el-card class="box-card"><h2>登录</h2><el-form:model="ruleForm"status-icon:rules="rules"ref="ruleForm"label-position="left"label-width="70px"class="login-from"><el-form-item label="用户名" prop="username"><el-input v-model="ruleForm.username"></el-input></el-form-item><el-form-item label="密码" prop="password"><el-inputtype="password"v-model="ruleForm.password"autocomplete="off"></el-input></el-form-item></el-form><div class="btnGroup"><el-buttontype="primary"@click="submitForm('ruleForm')"v-loading="loading">登录</el-button><el-button @click="resetForm('ruleForm')">重置</el-button><router-link to="/register"><el-button style="margin-left: 10px">注册</el-button></router-link></div></el-card></div>
</template><script>export default {data() {return {ruleForm: {username: "",password: "",},rules: {username: [{ required: true, message: "用户名不能为空!", trigger: "blur" },],password: [{ required: true, message: "密码不能为空!", trigger: "blur" },],},loading: false, // 是否显示加载动画};},methods: {submitForm(formName) {// 验证表单中的账号密码是否有效,因为在上面rules中定义为了必填 required: truethis.$refs[formName].validate((valid) => {// 点击登录后,让登录按钮开始转圈圈(展示加载动画)this.loading = true;// 如果经过校验,账号密码都不为空,则发送请求到后端登录接口if (valid) {let _this = this;// 使用 axios 将登录信息发送到后端this.axios({url: "/api/admin/student/login",               // 请求地址method: "post",                       // 请求方法headers: {                            // 请求头"Content-Type": "application/json",},data: {                             // 请求参数username: _this.ruleForm.username,password: _this.ruleForm.password,},}).then((res) => { // 当收到后端的响应时执行该括号内的代码,res 为响应信息,也就是后端返回的信息if (res.data.code === 1) {  // 当响应的编码为 1 时,说明登录成功// 将用户信息存储到sessionStorage中sessionStorage.setItem("userInfo", JSON.stringify(res.data.data));// 跳转页面到首页this.$router.push('/home');// 显示后端响应的成功信息this.$message({message: res.data.data,type: "success",});} else {  // 当响应的编码不为 1 时,说明登录失败// 显示后端响应的失败信息this.$message({message: res.data.msg,type: "warning",});}// 不管响应成功还是失败,收到后端响应的消息后就不再让登录按钮显示加载动画了_this.loading = false;console.log(res);});} else {  // 如果账号或密码有一个没填,就直接提示必填,不向后端请求console.log("error submit!!");this.loading = false;return false;}});},resetForm(formName) {this.$refs[formName].resetFields();},},
};
</script><style scoped>
/* 设置登录面板居中,宽度为400px */
.box-card {margin: auto auto;width: 400px;
}
/* 设置登录面板中的表单居中 */
.login-from {margin: auto auto;
}
</style>

src\views\home\Home.vue

<template><div><h2>欢迎{{ user.username }}!您的 uid 为{{ user.id }}</h2><el-button @click="logout"> 登出 </el-button></div>
</template><script>
export default {data() {return {user: {username: "",id: null,},};},methods: {logout(){// 移除本地用户登录信息sessionStorage.removeItem('userInfo');// 跳转页面到登录页this.$router.push('/login');}},mounted() {if (sessionStorage.getItem('userInfo')) {// 将用户信息存储到sessionStorage中this.user = JSON.parse(sessionStorage.getItem('userInfo'));}},
};
</script><style scoped>
</style>

src\router\index.js

// 此文件专门负责项目的路由import VueRouter from "vue-router"// 引入组件
import Login from '../views/login/Login'
import Register from '@/views/register/Register.vue'
import Home from '@/views/home/Home.vue'// 创建并暴露一个路由器
export default new VueRouter({mode: 'history',    // 路由模式,该模式不会在地址中显示井号#routes: [{path: '/',          // 路径redirect: '/login'  // 重定向},{path: '/login',     // 路径component: Login    // 跳转到的组件},{path: '/register',     // 路径component: Register    // 跳转到的组件},{path: '/home',     // 路径component: Home    // 跳转到的组件}]
})

修改一下登录界面

去掉注册功能

src\views\login\Login.vue

删除红色框部分

src\views\register

src\router\index.js

添加背景图片

src\views\login\Login.vue

测试

完整代码

src\views\login\Login.vue

<template><div class="login-background"><el-card class="box-card"><h2>体育器材管理后台</h2><el-form:model="ruleForm"status-icon:rules="rules"ref="ruleForm"label-position="left"label-width="70px"class="login-from"><el-form-item label="用户名" prop="username"><el-input v-model="ruleForm.username"></el-input></el-form-item><el-form-item label="密码" prop="password"><el-inputtype="password"v-model="ruleForm.password"autocomplete="off"></el-input></el-form-item></el-form><div class="btnGroup"><el-buttontype="primary"@click="submitForm('ruleForm')"v-loading="loading">登录</el-button><el-button @click="resetForm('ruleForm')">重置</el-button></div></el-card></div>
</template><script>export default {data() {return {ruleForm: {username: "",password: "",},rules: {username: [{ required: true, message: "用户名不能为空!", trigger: "blur" },],password: [{ required: true, message: "密码不能为空!", trigger: "blur" },],},loading: false, // 是否显示加载动画};},methods: {submitForm(formName) {// 验证表单中的账号密码是否有效,因为在上面rules中定义为了必填 required: truethis.$refs[formName].validate((valid) => {// 点击登录后,让登录按钮开始转圈圈(展示加载动画)this.loading = true;// 如果经过校验,账号密码都不为空,则发送请求到后端登录接口if (valid) {let _this = this;// 使用 axios 将登录信息发送到后端this.axios({url: "/api/admin/student/login",               // 请求地址method: "post",                       // 请求方法headers: {                            // 请求头"Content-Type": "application/json",},data: {                             // 请求参数username: _this.ruleForm.username,password: _this.ruleForm.password,},}).then((res) => { // 当收到后端的响应时执行该括号内的代码,res 为响应信息,也就是后端返回的信息if (res.data.code === 1) {  // 当响应的编码为 1 时,说明登录成功// 将用户信息存储到sessionStorage中sessionStorage.setItem("userInfo", JSON.stringify(res.data.data));// 跳转页面到首页this.$router.push('/home');// 显示后端响应的成功信息this.$message({message: res.data.data,type: "success",});} else {  // 当响应的编码不为 1 时,说明登录失败// 显示后端响应的失败信息this.$message({message: res.data.msg,type: "warning",});}// 不管响应成功还是失败,收到后端响应的消息后就不再让登录按钮显示加载动画了_this.loading = false;console.log(res);});} else {  // 如果账号或密码有一个没填,就直接提示必填,不向后端请求console.log("error submit!!");this.loading = false;return false;}});},resetForm(formName) {this.$refs[formName].resetFields();},},
};
</script><style scoped>
/* 设置登录面板居中,宽度为400px */
.box-card {margin: auto auto;width: 400px;
}
/* 设置登录面板中的表单居中 */
.login-from {margin: auto auto;
}/* 背景图片 */
.login-background {  background-image: url('/src/assets/bg.jpeg');  background-size: cover;  background-position: center;  height: 100vh;  display: flex; /* 如果你想要使用Flexbox来居中el-card  */ justify-content: center; /* 水平居中 */  align-items: center; /* 垂直居中 */  
}  
</style>

相关文章:

开始尝试从0写一个项目--前端(一)

基础项目构建 创建VUE初始工程 确保自己下载了node.js和npm node -v //查看node.js的版本 npm -v //查看npm的版本 npm i vue/cli -g //安装VUE CLI 创建 以管理员身份运行 输入&#xff1a;vue ui 就会进入 点击创建 自定义项目名字&#xff0c;选择npm管理 结…...

【Java探索之旅】多态:向上下转型、多态优缺点、构造函数陷阱

文章目录 &#x1f4d1;前言一、向上转型和向下转型1.1 向上转型1.2 向下转型 二、多态的优缺点2.1 多态优点2.2 多态缺陷 三、避免避免构造方法中调用重写的方法四、好的习惯&#x1f324;️全篇总结 &#x1f4d1;前言 在面向对象编程中&#xff0c;向上转型和向下转型是常用…...

Linux上web服务器搭建(Apache、Nginx)

第五章 web服务器 第一节 DNS&#xff1a;对域名进行解析&#xff0c;查询对应的地址 1.1 web服务器简介 www是world wide web的缩写&#xff0c;也就是全球信息广播的意思 1.2.网址及HTTP简介 web服务器提供的这些数据大部分都是文件&#xff0c;那么我们需要在服务器端…...

Django QuerySet对象,exclude()方法

模型参考上一章内容&#xff1a; Django QuerySet对象&#xff0c;filter()方法-CSDN博客 exclude()方法&#xff0c;用于排除符合条件的数据。 1&#xff0c;添加视图函数 Test/app11/views.py from django.shortcuts import render from .models import Postdef index(re…...

Qt/C++音视频开发78-获取本地摄像头支持的分辨率/帧率/格式等信息/mjpeg/yuyv/h264

一、前言 上一篇文章讲到用ffmpeg命令方式执行打印到日志输出&#xff0c;可以拿到本地摄像头设备信息&#xff0c;顺藤摸瓜&#xff0c;发现可以通过执行 ffmpeg -f dshow -list_options true -i video“Webcam” 命令获取指定摄像头设备的分辨率帧率格式等信息&#xff0c;会…...

Go bufio包

bufio包&#xff1a; 带缓冲的I/O操作&#xff0c; 减少系统调用次数&#xff0c; 读取文件、网络数据。 bufio包 是什么 bufio 包是 Go 标准库中的一个非常有用的包&#xff0c;用于提供带缓冲的 I/O 操作。它通过缓冲来提高读取和写入的效率&#xff0c;可以有效减少系统调用…...

C++ 类和对象 拷贝构造函数

一 拷贝构造函数的概念&#xff1a; 拷贝构造函数是一种特殊的构造函数&#xff0c;用于创建一个对象是另一个对象的副本。当需要用一个已存在的对象来初始化一个新对象时&#xff0c;或者将对象传递给函数或从函数返回对象时&#xff0c;会调用拷贝构造函数。 二 拷贝构造函…...

C# —— Math对象

Math 数学类 提供了一些相关数学计算的属性和方法、四舍五入、向上求整、向下求整、开平方&#xff0c;几次方 最大值和最小值 sin cos 绝对值 方法 1.Math 常用的字段 Math.PI double x 2 * 180 / Math.PI; Console.WriteLine(x); 2 Math.Abs() 求绝对值 int a -3; Con…...

Face_recognition实现人脸识别

这里写自定义目录标题 欢迎使用Markdown编辑器一、安装人脸识别库face_recognition1.1 安装cmake1.2 安装dlib库1.3 安装face_recognition 二、3个常用的人脸识别案例2.1 识别并绘制人脸框2.2 提取并绘制人脸关键点2.3 人脸匹配及标注 欢迎使用Markdown编辑器 本文基于face_re…...

1-3分钟爆款视频素材在哪找啊?这9个热门爆款素材网站分享给你

在如今快节奏的时代&#xff0c;短视频已成为吸引观众注意力的黄金手段。然而&#xff0c;要制作出1-3分钟的爆款视频&#xff0c;除了创意和剪辑技巧外&#xff0c;选择合适的素材至关重要。那么&#xff0c;哪里可以找到那些能让你的视频脱颖而出的爆款素材呢&#xff1f;不用…...

武汉免费 【FPGA实战训练】 Vivado入门与设计师资课程

一&#xff0e;背景介绍 当今高度数字化和智能化的工业领域&#xff0c;对高效、灵活且可靠的技术解决方案的需求日益迫切。随着工业 4.0 时代的到来&#xff0c;工业生产过程正经历着前所未有的变革&#xff0c;从传统的机械化、自动化逐步迈向智能化和信息化。在这一背景下&…...

【vite创建项目】

搭建vue3tsvitepinia框架 一、安装vite并创建项目1、用vite构建项目2、配置vite3、找不到模块 “path“ 或其相对应的类型声明。 二、安装element-plus1、安装element-plus2、引入框架 三、安装sass sass-loader1、安装sass 四、安装vue-router-next 路由1、安装vue-router42搭…...

最优化方法 运筹学【】

1.无约束 常用公式 线搜索准则&#xff1a;求步长 精确线搜索&#xff08;argmin&#xff09; 最速下降&#xff1a;sd&#xff1a;线性收敛 2.算法 SD dk&#xff1a;付梯度-g newton dk&#xff1a;Gkd-g 二阶收敛&#xff0c;步长为1 阻尼牛顿&#xff1a;步长用先搜…...

探索 WebKit 的动感世界:设备方向和运动支持全解析

探索 WebKit 的动感世界&#xff1a;设备方向和运动支持全解析 随着移动设备的普及&#xff0c;网页应用对设备方向和运动的感知需求日益增长。WebKit 作为众多流行移动浏览器的渲染引擎&#xff0c;提供了对设备方向和运动的全面支持&#xff0c;使得 Web 应用能够根据设备的…...

高考假期预习指南

IT专业入门&#xff0c;高考假期预习指南 对于希望进入IT行业的学生来说&#xff0c;假期是学习信息技术的最佳时机。 在信息化快速发展的时代&#xff0c;IT行业的发展前景广阔&#xff0c;但高技能要求使新生可能感到迷茫。 建议新生制定详细的学习计划&#xff0c;包括了解…...

Spring Boot 事件监听机制工作原理

前言&#xff1a; 我们知道在 Spring 、Spring Boot 的启动源码中都大量的使用了事件监听机制&#xff0c;也就是我们说的的监听器&#xff0c;监听器的实现基于观察者模式&#xff0c;也就是我们所说的发布订阅模式&#xff0c;这种模式可以在一定程度上实现代码的解耦&#…...

【AI大模型】驱动的未来:穿戴设备如何革新血液、皮肤检测与营养健康管理

文章目录 1. 引言2. 现状与挑战3. AI大模型与穿戴设备概述4. 数据采集与预处理4.1 数据集成与增强4.2 数据清洗与异常检测 5. 模型架构与训练5.1 高级模型架构5.2 模型训练与调优 6. 个性化营养建议系统6.1 营养建议生成优化6.2 用户反馈与系统优化 7. 关键血液成分与健康状况评…...

【FFmpeg】avcodec_open2函数

目录 1. avcodec_open21.1 编解码器的预初始化&#xff08;ff_encode_preinit & ff_decode_preinit&#xff09;1.2 编解码器的初始化&#xff08;init&#xff09;1.3 释放编解码器&#xff08;ff_codec_close&#xff09; FFmpeg相关记录&#xff1a; 示例工程&#xff…...

matlab:对带参数a关于x的方程求解

题目 讲解 简洁对各个式子的内部含义用浅显易懂的话语总结出来了&#xff0c;耐心体会 f(a) (x)exp(x)x^ax^(sqrt(x))-100;%因为下面的fzero的第一个数需要一个fun&#xff0c;所以这里有两个句柄&#xff0c;第一个a是输入的&#xff0c;第二个x是需要被解出的 A0:0.1:2;%创…...

Yolov10训练,转化onnx,推理

yolov10对于大目标的效果好&#xff0c;小目标不好 一、如果你训练过yolov5&#xff0c;yolov8&#xff0c;的话那么你可以直接用之前的环境就行 目录 一、如果你训练过yolov5&#xff0c;yolov8&#xff0c;的话那么你可以直接用之前的环境就行 二、配置好后就可以配置文件…...

基于算法竞赛的c++编程(28)结构体的进阶应用

结构体的嵌套与复杂数据组织 在C中&#xff0c;结构体可以嵌套使用&#xff0c;形成更复杂的数据结构。例如&#xff0c;可以通过嵌套结构体描述多层级数据关系&#xff1a; struct Address {string city;string street;int zipCode; };struct Employee {string name;int id;…...

Leetcode 3576. Transform Array to All Equal Elements

Leetcode 3576. Transform Array to All Equal Elements 1. 解题思路2. 代码实现 题目链接&#xff1a;3576. Transform Array to All Equal Elements 1. 解题思路 这一题思路上就是分别考察一下是否能将其转化为全1或者全-1数组即可。 至于每一种情况是否可以达到&#xf…...

ESP32读取DHT11温湿度数据

芯片&#xff1a;ESP32 环境&#xff1a;Arduino 一、安装DHT11传感器库 红框的库&#xff0c;别安装错了 二、代码 注意&#xff0c;DATA口要连接在D15上 #include "DHT.h" // 包含DHT库#define DHTPIN 15 // 定义DHT11数据引脚连接到ESP32的GPIO15 #define D…...

服务器硬防的应用场景都有哪些?

服务器硬防是指一种通过硬件设备层面的安全措施来防御服务器系统受到网络攻击的方式&#xff0c;避免服务器受到各种恶意攻击和网络威胁&#xff0c;那么&#xff0c;服务器硬防通常都会应用在哪些场景当中呢&#xff1f; 硬防服务器中一般会配备入侵检测系统和预防系统&#x…...

剑指offer20_链表中环的入口节点

链表中环的入口节点 给定一个链表&#xff0c;若其中包含环&#xff0c;则输出环的入口节点。 若其中不包含环&#xff0c;则输出null。 数据范围 节点 val 值取值范围 [ 1 , 1000 ] [1,1000] [1,1000]。 节点 val 值各不相同。 链表长度 [ 0 , 500 ] [0,500] [0,500]。 …...

江苏艾立泰跨国资源接力:废料变黄金的绿色供应链革命

在华东塑料包装行业面临限塑令深度调整的背景下&#xff0c;江苏艾立泰以一场跨国资源接力的创新实践&#xff0c;重新定义了绿色供应链的边界。 跨国回收网络&#xff1a;废料变黄金的全球棋局 艾立泰在欧洲、东南亚建立再生塑料回收点&#xff0c;将海外废弃包装箱通过标准…...

页面渲染流程与性能优化

页面渲染流程与性能优化详解&#xff08;完整版&#xff09; 一、现代浏览器渲染流程&#xff08;详细说明&#xff09; 1. 构建DOM树 浏览器接收到HTML文档后&#xff0c;会逐步解析并构建DOM&#xff08;Document Object Model&#xff09;树。具体过程如下&#xff1a; (…...

高危文件识别的常用算法:原理、应用与企业场景

高危文件识别的常用算法&#xff1a;原理、应用与企业场景 高危文件识别旨在检测可能导致安全威胁的文件&#xff0c;如包含恶意代码、敏感数据或欺诈内容的文档&#xff0c;在企业协同办公环境中&#xff08;如Teams、Google Workspace&#xff09;尤为重要。结合大模型技术&…...

【学习笔记】深入理解Java虚拟机学习笔记——第4章 虚拟机性能监控,故障处理工具

第2章 虚拟机性能监控&#xff0c;故障处理工具 4.1 概述 略 4.2 基础故障处理工具 4.2.1 jps:虚拟机进程状况工具 命令&#xff1a;jps [options] [hostid] 功能&#xff1a;本地虚拟机进程显示进程ID&#xff08;与ps相同&#xff09;&#xff0c;可同时显示主类&#x…...

tree 树组件大数据卡顿问题优化

问题背景 项目中有用到树组件用来做文件目录&#xff0c;但是由于这个树组件的节点越来越多&#xff0c;导致页面在滚动这个树组件的时候浏览器就很容易卡死。这种问题基本上都是因为dom节点太多&#xff0c;导致的浏览器卡顿&#xff0c;这里很明显就需要用到虚拟列表的技术&…...