Vue3项目练习详细步骤(第一部分:项目构建,登录注册页面)

项目环境准备 

工程创建 

安装依赖 

项目调整

注册功能

页面结构 

接口文档

 数据绑定和校验

 数据接口调用

解决跨域问题

 登录功能

接口文档

数据绑定和校验

 数据接口调用

优化登录/注册成功提示框

项目演示

项目的后端接口参考:https://blog.csdn.net/dafsq/category_12646722.html?spm=1001.2014.3001.5482

项目环境准备 

工程创建 

到需要的目录下使用命令创建vue 项目

vue create 项目名

 选择默认创建vue3项目

安装依赖 

创建成功后在项目目录下安装第三方依赖

npm install element-plus --save
npm install @element-plus/icons-vue
npm install axios
npm install sass -D

项目调整

Visual Studio Code打开项目目录

 修改main.js中的内容

import { createApp } from 'vue'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import App from './App.vue'
import locale from 'element-plus/dist/locale/zh-cn'

const app = createApp(App)
 
app.use(ElementPlus,{locale})
app.mount('#app')

删除项目下components目录中的所有内容

在src目录下新建api、utils、views这三个目录 

在utils目录下新建请求工具文件request.js 

//定制请求的实例

//导入axios  npm install axios
import axios from 'axios';
//定义一个变量,记录公共的前缀  ,  baseURL
const baseURL = 'http://localhost:8080';
const instance = axios.create({baseURL})


//添加响应拦截器
instance.interceptors.response.use(
    result=>{
        return result.data;
    },
    err=>{
        alert('服务异常');
        return Promise.reject(err);//异步的状态转化成失败的状态
    }
)

export default instance;

 将项目需要的静态资源复制到assets目录下

静态资源获取:https://download.csdn.net/download/dafsq/89349949?spm=1001.2014.3001.5503

 修改App.vue中的内容

<template>
  <div>hello vue3</div>
</template>

<script>

export default {
  name: 'App',
  components: {
  }
}
</script>

<style>

</style>

 在项目目录下启动项目

npm run serve

访问查看

注册功能

页面结构 

 在views目录下新建Login.vue文件

在Login.vue 文件中完善代码

<script setup>
import { User, Lock } from '@element-plus/icons-vue'
import { ref } from 'vue'
//控制注册与登录表单的显示, 默认显示注册
const isRegister = ref(false)
</script>

<template>
    <el-row class="login-page">
        <el-col :span="12" class="bg"></el-col>
        <el-col :span="6" :offset="3" class="form">
            <!-- 注册表单 -->
            <el-form ref="form" size="large" autocomplete="off" v-if="isRegister">
                <el-form-item>
                    <h1>注册</h1>
                </el-form-item>
                <el-form-item>
                    <el-input :prefix-icon="User" placeholder="请输入用户名"></el-input>
                </el-form-item>
                <el-form-item>
                    <el-input :prefix-icon="Lock" type="password" placeholder="请输入密码"></el-input>
                </el-form-item>
                <el-form-item>
                    <el-input :prefix-icon="Lock" type="password" placeholder="请输入再次密码"></el-input>
                </el-form-item>
                <!-- 注册按钮 -->
                <el-form-item>
                    <el-button class="button" type="primary" auto-insert-space>
                        注册
                    </el-button>
                </el-form-item>
                <el-form-item class="flex">
                    <el-link type="info" :underline="false" @click="isRegister = false">
                        ← 返回
                    </el-link>
                </el-form-item>
            </el-form>
            <!-- 登录表单 -->
            <el-form ref="form" size="large" autocomplete="off" v-else>
                <el-form-item>
                    <h1>登录</h1>
                </el-form-item>
                <el-form-item>
                    <el-input :prefix-icon="User" placeholder="请输入用户名"></el-input>
                </el-form-item>
                <el-form-item>
                    <el-input name="password" :prefix-icon="Lock" type="password" placeholder="请输入密码"></el-input>
                </el-form-item>
                <el-form-item class="flex">
                    <div class="flex">
                        <el-checkbox>记住我</el-checkbox>
                        <el-link type="primary" :underline="false">忘记密码?</el-link>
                    </div>
                </el-form-item>
                <!-- 登录按钮 -->
                <el-form-item>
                    <el-button class="button" type="primary" auto-insert-space>登录</el-button>
                </el-form-item>
                <el-form-item class="flex">
                    <el-link type="info" :underline="false" @click="isRegister = true">
                        注册 →
                    </el-link>
                </el-form-item>
            </el-form>
        </el-col>
    </el-row>
</template>

<style lang="scss" scoped>
/* 样式 */
.login-page {
    height: 100vh;
    background-color: #fff;

    .bg {
        background: url('@/assets/logo2.png') no-repeat 60% center / 240px auto,
            url('@/assets/login_bg.jpg') no-repeat center / cover;
        border-radius: 0 20px 20px 0;
    }

    .form {
        display: flex;
        flex-direction: column;
        justify-content: center;
        user-select: none;

        .title {
            margin: 0 auto;
        }

        .button {
            width: 100%;
        }

        .flex {
            width: 100%;
            display: flex;
            justify-content: space-between;
        }
    }
}
</style>

 在App.vue文件中引入Login.vue

注意如果发现项目报错:Module not found: Error: Can't resolve 'sass-loader' in 'D:\vue\vue_app'

有很多种情况,比如没安装SASS加载器 或者是安装了版本太高,不支持,下面这种是解决版本过高问题的

 在项目目录下运行以下命令

//首先清除我们已经安装过的版本:
npm uninstall node-sass 
npm uninstall sass-loader
npm uninstall style-loader
//注意我们清除的时候可以选择全局的清除 全局的安装,否则下次创建 项目还会有同样的错误 执行重复的操作
npm i node-sass --sass_binary_site=https://npm.taobao.org/mirrors/node-sass/  //淘宝镜像安装
npm install sass-loader@7.3.1 --save-dev    //安装7.3.1版本的sass
npm install style-loader --save-dev // 安装style-loader



在main.js中引入静态文件包下的main.scss文件

import'./assets/main.scss'

保存刷新后查看页面 

接口文档

 数据绑定和校验

定义数据模型

//定义数据模型
const registerData = ref({
    username:'',
    password:'',
    rePassword:''
})

将数据绑定给表单

对表单项进行校验 

//二次校验密码的函数
const checkRePassword = (rule,value,callback) => {
    if(value == ''){
        callback(new Error('请再次确认密码'))
    } else if( value !== registerData.value.password){
        callback('二次确认密码不相同请重新输入')
    } else{
        callback()
    }
}

//定义表单校验规则
const rules = ref({
    username:[
        {required:true,massage:'请输入用户名',trigger:'blur'},
        {min:5,max:16,message:'请输入长度5~16非空字符',trigger:'blur'}
    ],
    password:[
        {required:true,massage:'请输入密码',trigger:'blur'},
        {min:5,max:16,message:'请输入长度5~16非空字符',trigger:'blur'}
    ],
    rePassword:[{validator:checkRePassword,trigger:'blur'}] //校验二次输入密码是否相同
})

绑定表单校验

 保存刷新查看校验效果

 数据接口调用

  • 将之前的springboot项目启动
  • 启动redis

在api目录下创建user.js文件 

 在文件中完成调用接口函数的编写

//导入request.js请求工具
import request from '@/utils/request.js'

//提供调用注册接口的函数
export const userRegisterService = (registerData) => {
    //借助UrlSearchParams完成传递
    const params = new URLSearchParams()
    for (let key in registerData){
        params.append(key,registerData[key]);
    }

    return request.post('/user/register',params);
}

定义调用接口注册函数

//调用后台接口完成注册
import {userRegisterService} from '@/api/user.js'
const register = async () => {
    //registerData是一个响应式对象,调用时现需要加上.value
    let result = await userRegisterService(registerData.value);
    if(result.code == 0) {
        //成功
        alert(result.msg ? result.massage:'注册成功');
    }else{
        //失败
        alert('注册失败')
    }
}

 在注册按钮处绑定注册请求单击事件

解决跨域问题

        由于浏览器的同源策略限制,向不同源(不同协议、不同域名、不同端口)发送ajax请求会失败 

在vue.config.js文件中完成配置代理

module.exports={
  lintOnSave:false, //关闭eslint语法检查配置
  devServer:{
    proxy:{
      '/api':{
        target:'http://localhost:8888', //这里后台的地址模拟的;应该填写你们真实的后台接口
        ws:false,
        changOrigin:true, //允许跨域
        pathRewrite:{'^/api':''}  //路径重写,请求的时候使用这个api就可以
      }
    }
  }
}

在request.js文件中将请求路径改为/api

 重启项目测试注册功能

已成功注册并且数据库中也成功添加了该用户的数据

 登录功能

接口文档

数据绑定和校验

        由于用户名和密码的数据和校验在定义注册数据模型是就已经定义好了,所以这里直接复用注册的数据和校验就可以了

 数据接口调用

在api文件中提供调用登录接口的函数

//提供调用登录接口的函数
export const userLoginService = (loginData) => {
    //借助UrlSearchParams完成传递
    const params = new URLSearchParams()
    for (let key in loginData){
        params.append(key,loginData[key]);
    }
    return request.post('/user/login',params);    
}

回到登录页面代码中完成登录单击事件函数 

//登录函数
import {userLoginService} from '@/api/user.js'
const login = async () =>{
    //调用接口完成登录
    let result = await userLoginService(registerData.value);
    if(result.code == 0){
        alert(result.msg ? result.msg : '登录成功')
    }else{
        alert('登录失败')
    }
}

给登录按钮绑定单击事件 

因为登录和注册是绑定的同一个数据模模型,所以要在每次登录和注册切换时清空数据

//定义函数,清空数据模型
const clearRegisterData = () =>{
    registerData.value = {
        username:'',
        password:'',
        rePassword:''
    }
}

 在切换注册和返回的按钮中绑定清空数据函数

刷新保存到页面中登录查看

优化登录/注册成功提示框

 在登录页面文件中导入组件修改登录函数内容

import { ElMessage } from 'element-plus'

ElMessage.error('服务异常');
ElMessage.success('登录成功!')

 保存运行查看效果

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/654336.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

selenium 学习笔记(一)

pip的安装 新建一个txt curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py 把上面的代码复制进去后&#xff0c;把后缀名改为.bat然后双击运行 当前目录会出现一个这个文件 然后在命令行pyhon get-pip.py等它下好就可以了selenium安装 需要安装到工程目…

第15章-超声波避障功能 HC-SR04超声波测距模块详解STM32超声波测距

这个是全网最详细的STM32项目教学视频。 第一篇在这里: 视频在这里 STM32智能小车V3-STM32入门教程-openmv与STM32循迹小车-stm32f103c8t6-电赛 嵌入式学习 PID控制算法 编码器电机 跟随 15.1-超声波测距 完成超声波测距功能、测量数据显示在OLED屏幕上 硬件介绍 使用&#…

react 保持组件纯粹

部分 JavaScript 函数是 纯粹 的&#xff0c;这类函数通常被称为纯函数。纯函数仅执行计算操作&#xff0c;不做其他操作。你可以通过将组件按纯函数严格编写&#xff0c;以避免一些随着代码库的增长而出现的、令人困扰的 bug 以及不可预测的行为。但为了获得这些好处&#xff…

【问题解决】huggingface 离线模型下载

问题 因业务需要在本机测试embedding分词模型&#xff0c;使用 huggingface上的transformers 加载模型时&#xff0c;因为网络无法访问&#xff0c;不能从 huggingface 平台下载模型并加载出现如下错误。 下面提供几种模型下载办法 解决 有三种方式下载模型&#xff0c;一种是通…

《书生·浦语大模型实战营》第1课 学习笔记:书生·浦语大模型全链路开源体系

文章大纲 1. 简介与背景智能聊天机器人与大语言模型目前的开源智能聊天机器人与云上运行模式 2. InternLM2 大模型 简介3. 视频笔记&#xff1a;书生浦语大模型全链路开源体系内容要点从模型到应用典型流程全链路开源体系 4. 论文笔记:InternLM2 Technical Report简介软硬件基础…

苹果手机数据不慎删除?这4个方法果粉必看!

苹果手机该怎么恢复丢失的数据呢&#xff1f;有时候会因为使用不当或者是被他人误删等原因&#xff0c;导致重要的数据丢失&#xff0c;这时我们需要找回丢失手机数据&#xff0c;小编给大家分享4种恢复苹果手机数据的技巧&#xff0c;大家赶紧来学一学吧&#xff01; 一、iclo…

618有哪些值得买的好物?这几款好物通宵整理吐血推荐!

随着618购物节越来越近&#xff0c;很多买家终于等到了用好价钱买好东西的好机会。不管是你一直想要的家居电器&#xff0c;还是最新的数码产品&#xff0c;平时挺贵的东西在618期间会便宜不少。不过&#xff0c;这么多东西可选&#xff0c;促销活动也多得让人看花了眼&#xf…

SAM遥感图像处理开源新SOTA!在GPU上实现40倍加速,不损准确性

在遥感图像处理领域&#xff0c;通过SAM捕捉复杂图像特征和细微差异&#xff0c;可以实现高精度的图像分割&#xff0c;提升遥感数据的处理效率。这种高度的准确性让SAM遥感展现出了比传统方法更优越的性能。 不仅如此&#xff0c;这种策略灵活普适的特性还能拓展遥感技术的应…

Python | Leetcode Python题解之第102题二叉树的层序遍历

题目&#xff1a; 题解&#xff1a; class Solution:def levelOrder(self, root: Optional[TreeNode]) -> List[List[int]]:if not root: return []res, queue [], collections.deque()queue.append(root)while queue:tmp []for _ in range(len(queue)):node queue.popl…

Unity3D让BoxCollider根据子物体生成自适应大小

系列文章目录 unity工具 文章目录 系列文章目录unity工具 &#x1f449;前言&#x1f449;一、编辑器添加&#x1f449;二、代码动态添加的方法(第一种)&#x1f449;三、代码动态添加的方法(第二种)&#x1f449;四、重新设置模型的中心点&#x1f449;壁纸分享&#x1f449;…

分布式事务解决方案(最终一致性【可靠消息解决方案】)

可靠消息最终一致性解决方案 可靠消息最终一致性分布式事务解决方案指的是事务的发起方执行完本地事务之后&#xff0c;发出一条消息&#xff0c;事务的参与方&#xff0c;也就是消息的消费者一定能够接收到这条消息并且处理完成&#xff0c;这个方案强调的是只要事务发起方将消…

03 FreeRTOS 同步互斥与通信

1、同步与互斥 一句话理解同步与互斥&#xff1a;我等你用完厕所&#xff0c;我再用厕所。 什么叫同步&#xff1f;就是&#xff1a;哎哎哎&#xff0c;我正在用厕所&#xff0c;你等会。 什么叫互斥&#xff1f;就是&#xff1a;哎哎哎&#xff0c;我正在用厕所&#xff0c;你…

太阳能语音监控杆(球机LED款)有什么用

传统监控设备依赖电力支持&#xff0c;在偏远地区和没有网络地区难以发挥其作用&#xff0c;而鼎跃安全的太阳能语音监控杆&#xff08;球机LED款&#xff09;在传统监控基础上&#xff0c;进行了全面优化&#xff0c;解决了无电无网区域使用受限的问题。 太阳能语音监控杆&am…

关于已配好java环境但双击无法打开jar包的解决方案

如果你已经装好了 java 环境直接跳到最后看解决方法即可 先说一下你安装的 java 环境&#xff0c;如果完全是默认选项安装&#xff0c;则会安装 jdk 和 jre&#xff0c;并且在安装 jre 时还需要安装目录下为空&#xff0c;其实 jre 的安装是多余的&#xff0c;因为安装的 jdk 里…

无人机侦察:雷达系统概述

一、雷达基本原理 无人机侦察中的雷达系统主要基于无线电波的传播和反射原理。雷达发射机产生特定频率的电磁波&#xff0c;并通过天线以定向波束形式向空间发射。当这些电磁波遇到目标时&#xff0c;部分能量会被反射回来&#xff0c;被雷达接收机捕获。通过测量发射和接收电…

VUE3学习第一篇:启动ruoyi

1、找到ruoyi的vue3版本 然后下载代码到本地&#xff0c; 我刚开始用的nodejs14报错&#xff0c; 后面换成nodejs16&#xff0c;启动前端成功了。 页面如下图所示

记一次Chanakya靶机的渗透测试

Chanakya靶机渗透测试 首先通过主机发现发现到靶机的IP地址为:172.16.10.141 然后使用nmap工具对其进行扫描:nmap -sC -sV -sS -p- 172.16.10.141 发现目标靶机开启了80,22,21等多个端口&#xff0c; 访问80端口,发现是一个普通的页面,点击进入多个界面也没有其他有用的信息,然…

ArcgisPro3.1.5安装手册

ArcgisPro3.1.5安装手册 一、目录介绍: 二、安装教程&#xff1a; (1)安装顺序&#xff1a;最先安装运行环境&#xff08;runtime6.0.5&#xff09;,接着安装install里面的文件&#xff0c;最后复制path里面的文件替换到软件bin文件夹下即可。 (2)具体安装步骤&#xff…

图算法新书发布会圆满成功,大咖现场都讲了啥?

5月24日&#xff0c;嬴图与机工社携手举办的“《图算法&#xff1a;行业应用与实践》新书发布会”圆满成功。 现场直播在线观众达4000人/次左右&#xff0c;点赞数量超7000&#xff0c;直至发布会尾声&#xff0c;观看人数仍在持续增长。 通过观众们的反馈&#xff0c;我们也对…