【全栈】SprintBoot+vue3迷你商城(7)

发布于:2025-02-10 ⋅ 阅读:(57) ⋅ 点赞:(0)

【全栈】SprintBoot+vue3迷你商城(7)

往期的文章都在这里啦,大家有兴趣可以看一下

后端部分:

【全栈】SprintBoot+vue3迷你商城(1)
【全栈】SprintBoot+vue3迷你商城(2)
【全栈】SprintBoot+vue3迷你商城-扩展:利用python爬虫爬取商品数据
【全栈】SprintBoot+vue3迷你商城(3)
【全栈】SprintBoot+vue3迷你商城(4)
【全栈】SprintBoot+vue3迷你商城(5)
【全栈】SprintBoot+vue3迷你商城(6)

前端部分:

【全栈】SprintBoot+vue3迷你商城-扩展:vue的基本用法

【全栈】SprintBoot+vue3迷你商城-扩展:vue3项目创建及目录介绍

本期我们开始迷你商城前端的开发

1.安装所需依赖

1.1.Element-Plus

npm install element-plus --save

1.2.Axios

npm install axios

1.3.Sass

npm install sass -D

2.开发基本步骤

  • 首先需要搭建页面
  • 然后为页面绑定数据模型及事件
  • 之后再调用后端的接口

3.登录、注册页面的开发

3.1.搭建页面,绑定数据与函数

/src/views/Login.vue

<script setup>
import { User, Lock } from '@element-plus/icons-vue'
import { ref } from 'vue'
import { useRouter } from 'vue-router';
import { useTokenStore } from '@/stores/token'
import { ElMessage } from 'element-plus';
const router = useRouter();

const isRegister = ref(false)

const registerData = ref({
    username: '',
    userType: '',
    password: '',
    rePassword: ''
})

const clearRegisterData = () => {
    registerData.value = {
        username: '',
        password: '',
        rePassword: ''
    }
}
import { userLoginService, userRegisterService } from "@/api/user"
const login = async () => {
    let result = await userLoginService(registerData.value)
    ElMessage.success(result.msg ? result.msg : '登录成功');
    const tokenStore = useTokenStore()
    tokenStore.setToken(result.data)
    router.push('/')

}
const register = async () => {
    let result = await userRegisterService(registerData.value)
    ElMessage.success(result.msg ? result.msg : '注册成功');
    clearRegisterData();
    ElMessage.success('请登录')
}
const options= ref([
    '普通用户',
    '商家'
])

</script>

<template>
    <el-row class="login-page" style="background-color:lightpink;">
        <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="请输入用户名" v-model="registerData.username"></el-input>
                </el-form-item>

                <el-select placeholder="请选择用户类型" size="large" style="width: 208px;margin-bottom: 20px;" v-model="registerData.userType" >
                    <el-option v-for="item in options" :key="item" :value="item" />
                </el-select>

                <el-form-item>
                    <el-input :prefix-icon="Lock" type="password" placeholder="请输入密码"
                        v-model="registerData.password"></el-input>
                </el-form-item>
                <el-form-item>
                    <el-input :prefix-icon="Lock" type="password" placeholder="请输入再次密码"
                        v-model="registerData.rePassword"></el-input>
                </el-form-item>
                <el-form-item>
                    <el-button class="button" type="danger" @click="register()" auto-insert-space>
                        注册
                    </el-button>
                </el-form-item>
                <el-form-item class="flex">
                    <el-link type="info" :underline="false" @click="isRegister = false; clearRegisterData()"
                        style="color: coral;">
                        返回
                    </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="请输入用户名" v-model="registerData.username"></el-input>
                </el-form-item>
                <el-form-item>
                    <el-input name="password" :prefix-icon="Lock" type="password" placeholder="请输入密码"
                        v-model="registerData.password"></el-input>
                </el-form-item>
                <el-form-item>
                    <el-button class="button" type="danger" auto-insert-space @click="login()">登录</el-button>
                </el-form-item>
                <el-form-item class="flex">
                    <el-link type="info" :underline="false" @click="isRegister = true; clearRegisterData()"
                        style="color: coral;">
                        注册
                    </el-link>
                </el-form-item>
            </el-form>
        </el-col>
    </el-row>
</template>

<style lang="scss" scoped>
.login-page {
    height: 100vh;
    background: url('@/assets/logo2.jpg') no-repeat 88% 0% / 500px auto;


    .bg {
        background:
            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>

3.2.制定与后端接口交互的函数

/src/api/user.js

import request from '@/utils/request'

export const userRegisterService =(registerData)=>{
    const params =new URLSearchParams();
    for(let key in registerData){
        params.append(key ,registerData[key]);
    }
    return request.post('/user/register',params);
}

export const userLoginService=(loginData)=>{
    const params =new URLSearchParams();
    for(let key in loginData){
        params.append(key,loginData[key])
    }
    return request.post('/user/login',params);
}

3.3.制定统一请求入口以及请求、响应拦截器:

/src/utils/request.js

import axios from 'axios';
import {useTokenStore} from '@/stores/token'
import { ElMessage } from 'element-plus';
const baseURL = '/api';
const instance = axios.create({baseURL})


instance.interceptors.request.use(
    (config)=>{
        const tokenStore=useTokenStore();
        if (tokenStore.token){
            config.headers.Authorization=tokenStore.token
                }
        return config
    },
    (err)=>{
        Promise.reject(err);
    }
)


import router from '@/router';
//响应拦截器
instance.interceptors.response.use(
    result=>{
        if(result.data.code===0){
            return result.data;
        }
        ElMessage.error(result.data.msg?result.data.msg:'服务异常')
        return Promise.reject(result.data)
    },
    err=>{
        if (err.response.status===401){
            ElMessage.error('请先登录')
            router.push('/login')

        }else{
            ElMessage.error('服务异常')
        }
        return Promise.reject(err);
    }
)

export default instance;

3.4.解决跨域问题:

vite.config.js

import { fileURLToPath, URL } from 'node:url'

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import vueDevTools from 'vite-plugin-vue-devtools'

// https://vite.dev/config/
export default defineConfig({
  plugins: [
    vue(),
    vueDevTools(),
  ],
  resolve: {
    alias: {
      '@': fileURLToPath(new URL('./src', import.meta.url))
    },
  },
  server:{
    proxy:{
      '/api':{
        target:'http://localhost:8080',
        changeOrigin:true,
        rewrite:(path)=>path.replace(/^\/api/,'')
      }
    }
  }
})

如果有不懂的地方可以看【全栈】SprintBoot+vue3迷你商城-扩展:vue3项目创建及目录介绍

然后再结合这里面的代码示例

4.效果展示

初次尝试,页面制作的较为粗糙,请见谅

在这里插入图片描述

在这里插入图片描述

5.总结

本期我们进行了登录、注册页面的搭建以及接口绑定,下期我们将介绍登录后跳转的主页面的开发。


网站公告

今日签到

点亮在社区的每一天
去签到