6.创建vue3项目-实现管理员登录前端页面

飞一样的编程
飞一样的编程
擅长邻域:Java,MySQL,Linux,nginx,springboot,mongodb,微信小程序,vue

分类: springboot uni-app vue 专栏: 带小白springboot3+vue3+uniapp 标签: springboot3 vue uniapp

2026-01-17 15:57:07 99浏览

创建vue3项目-实现管理员登录前端页面

效果图

创建 vue3 项目

第六章 MyBatis-Plus+Vue+Element前后端分离实战-[springboot][springboot3.0新教材]博客-jf3q杰凡IT问答

这是我之前写的文章,可以参考下。

注意要安装 vue 脚手架.如果你没装的话

npm install -g @vue/cli

跨域问题解决+axios 配置

vue.config.js 修改这个文件即可

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

//以上是自动生成的,下面是为解决跨域加的
module.exports = {
  publicPath:'/',
  devServer: {
    host:'localhost',
    port:7777, //前端项目端口号 选填
    proxy:{
      [process.env.VUE_APP_BASE_API]: {
        target: `http://localhost:8888`, //后端项目地址
        changeOrigin: true,
        ws: true, // 是否支持 websocket, 默认是 true
        pathRewrite: {['^' + process.env.VUE_APP_BASE_API]: ''}
      }
    }
  }
}

要新建文件

.env.development 和.env.production

内容如下

# 开发环境配置
ENV = 'development'
VUE_APP_BASE_API = '/dev-api'
# 生产环境配置
ENV = 'production'
VUE_APP_BASE_API = '/prod-api'

axios 的配置 js


import axios from "axios";
import {ElMessage, ElMessageBox} from "element-plus";

// Full config:  https://github.com/axios/axios#request-config
// axios.defaults.baseURL = process.env.baseURL || process.env.apiUrl || '';
// axios.defaults.headers.common['Authorization'] = AUTH_TOKEN;
// axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';

let config = {
    // baseURL: process.env.baseURL || process.env.apiUrl || ""
    // timeout: 60 * 1000, // Timeout
    // withCredentials: true, // Check cross-site Access-Control
    baseURL: process.env.VUE_APP_BASE_API
    // dev-api/login

};

const _axios = axios.create(config);

_axios.interceptors.request.use(
    function(config) {
        // Do something before request is sent

        //向请求头放 token  这个操作每个发送axios都要操作的

        var token = sessionStorage.getItem("token");

        if(token){
            config.headers['token']=token
        }
        return config;
    },
    function(error) {
        // Do something with request error
        return Promise.reject(error);
    }
);

// Add a response interceptor
_axios.interceptors.response.use(
    function(response) {
        // Do something with response data

        if(response.data.code == 3000){

            ElMessageBox.confirm(response.data.mess,"系统提示",{
                    confirmButtonText:'重新登录',
                    cancelButtonText:'取消',
                    type:'warning'

                }

            ).then(()=>{
                location.href="/";

            })
            // 阻止进一步链式调用 没提示任何信息 不走then
            return new Promise(() => {});

        }else if(response.data.code==5000){
            ElMessage.error(response.data.mess)
            // 阻止进一步链式调用 没提示任何信息    不走then
            return new Promise(() => {});
        }else{
            //要走 then
            return response.data;


        }

    },
    function(error) {
        // Do something with response error
        return Promise.reject(error);
    }
);

// Vue 3 插件安装方式
const requestPlugin = {
    install(app) {
        app.config.globalProperties.$axios = _axios;
        app.provide('axios', _axios);
        window.axios = _axios;
    }
};

export default requestPlugin;
export {_axios as request}

注意要在 main.js 中引入

import { createApp } from 'vue'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import App from './App.vue'
import router from './router'
import store from './store'
import requestPlugin from './axios/index'

const app = createApp(App)

// 使用插件
app.use(store)
app.use(router)
app.use(ElementPlus)
app.use(requestPlugin)

// 挂载应用
app.mount('#app')

要跟你的 axios 的配置文件目录一致哦,我的是在前端项目根目录下的 axios 文件夹下的 index.js

axios 请求后端接口

请求登录接口的核心代码


// 提交表单
const submitForm = async () => {
  if (!loginFormRef.value) return

  await loginFormRef.value.validate(async (valid) => {
    if (valid) {
      try {
        // 调用登录API
        const res = await login( loginForm)
        console.log(res)

        ElMessage.success('登录成功')
        // 登录成功后跳转到首页
        router.push('/about')

      } catch (error) {
        console.error('登录错误:', error)
        ElMessage.error('登录失败,请重试')
      }
    }
  })
}

注意 await login( loginForm)是发请求到后端

import {login} from '@/api/index'这样引入 login 函数

import {request} from '@/axios/index'

export function login(query) {
    return request({
        url: '/login',
        method: 'post',
        params: query
    })
}

这个文件专门存放前端请求后端的所有接口

下面是之前写的分页查询的一个 vue3+elementplus 的 demo(备用参考)

<script setup>


import {onMounted, ref} from "vue";
import axios from  'axios'
import {ElMessage, ElMessageBox} from "element-plus";

const fileList=ref([])

const suceessFile = (response,uploadFile,uploadFiles) => {
  console.log(response)
  console.log(uploadFile)
  console.log(uploadFiles)
  fileList.value=[]

  if(response.code==5000){
    ElMessage.error(response.mess)
  }else{
    ElMessage.success(response.mess)

    getPage()
  }

}
const submitForm = () => {

  ruleFormRef.value.validate( (v)=>{
    if(v){

      //校验通过

      axios({
        url: '/api/stu/saveOrUpdate',
        method: 'post',
        data:ruleForm.value
      }).then(res => {
        console.log(res);

        if(res.data.code== 2000){
          ElMessage.success(res.data.mess)
          dialogVisible.value=false
          getPage()
        }else{
          ElMessage.error(res.data.mess)
        }
      })

    }else{

      //么按规矩填写表单
      ElMessage.error("请按提示填写表单")


    }
  })

}
const resetForm = () => {
  ruleFormRef.value.resetFields()

}
const onAdd = () => {
  dialogVisible.value=true


}

const formInline= ref({

  studentname: '',
  classno: ''

})

const changePageNum = (val) => {

  pageNum.value=val
  getPage()

}

const dialogVisible=ref(false)
const total= ref(0)
const pageNum= ref(1)
const pages= ref(0)
const pageSize= ref(3)

const tableData=ref([])

const onSubmit = () => {

  pageNum.value=1
  getPage()

}

const toUpdate = (row) => {
  console.log(row)

  ruleForm.value.gender=row.gender
  ruleForm.value.age=row.age
  ruleForm.value.address=row.address
  ruleForm.value.id=row.id
  ruleForm.value.studentname=row.studentname
  dialogVisible.value=true
}

const ruleForm= ref({
  id: '',
  studentname: '',
  age: '',
  gender: '',
  address: ''
})

const  rules= ref(
    {
      studentname: [
        { required: true, message: '请输入学生名字', trigger: 'blur' },
      ],
      age: [
        { required: true, message: '请输入学生年龄', trigger: 'blur' },
      ],
      gender: [
        { required: true, message: '请选择性别', trigger: 'blur' },
      ],
      address: [
        { required: true, message: '请输入地址', trigger: 'blur' },
      ],
    }
)

const ruleFormRef= ref(null)

const toDel = (id) => {
  ElMessageBox.confirm(
      '您确定要删除该记录吗?',
      'Warning',
      {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning',
      }
  )
      .then(() => {

        axios({
          url: '/api/stu/del/'+id,
          method:'delete',
        }).then(res => {
          if (res.data.code == 2000) {


            ElMessage({
              type: 'success',
              message: res.data.mess,
            })

            getPage()
          }else{
            ElMessage({
              type: 'error',
              message: res.data.mess,
            })
          }
        })

      })
      .catch(() => {
        ElMessage({
          type: 'info',
          message: '取消删除',
        })
      })

}

const getPage = () => {


  axios({
    url: '/api/stu/page?pageNum='+pageNum.value,
    method: 'get',
    params: formInline.value
  }).then(res => {
    console.log(res);

    tableData.value=res.data.data.records
    total.value=res.data.data.total
    pages.value=res.data.data.pages
    pageNum.value=res.data.data.current
    pageSize.value=res.data.data.size


  })
}

const classList=ref([])
onMounted( ()=>{

  axios({
    url: '/api/class',
  }).then(res => {
    console.log(res);
    classList.value=res.data.data
  })
  getPage()
})

const closeDialog = () => {

  resetForm()

  dialogVisible.value=false

}

</script>

<template>

  <div>
    <el-dialog

        @close="closeDialog"
        v-model="dialogVisible"
        title="新增/修改"
        width="500"
    >


      <el-form
          ref="ruleFormRef"
          style="max-width: 600px"
          :model="ruleForm"
          :rules="rules"
          label-width="auto"
          class="demo-ruleForm"
          status-icon
      >


        <el-form-item label="学生姓名" prop="studentname">
          <el-input v-model="ruleForm.studentname" />
        </el-form-item>

        <el-form-item label="性别" prop="gender">
          <el-radio-group v-model="ruleForm.gender">
            <el-radio value="男">男</el-radio>
            <el-radio value="女">女</el-radio>
          </el-radio-group>
        </el-form-item>

        <el-form-item label="学生年龄" prop="age">
          <el-input type="number" v-model="ruleForm.age" />
        </el-form-item>



        <el-form-item label="地址" prop="address">
          <el-input v-model="ruleForm.address" type="textarea" />
        </el-form-item>
        <el-form-item>
          <el-button type="primary" @click="submitForm(ruleFormRef)">
            确定
          </el-button>
          <el-button @click="resetForm(ruleFormRef)">重置</el-button>
        </el-form-item>
      </el-form>



    </el-dialog>
    <el-form :inline="true" :model="formInline" class="demo-form-inline">
      <el-form-item label="学生名字">
        <el-input v-model="formInline.studentname" placeholder="xxxx" clearable />
      </el-form-item>

      <el-form-item label="班级"  >

        <el-select v-model="formInline.classno" style="width: 200px" placeholder="请选择">
          <el-option value="" label="请选择班级" ></el-option>
          <el-option v-for="c in classList" :key="c.classno" :value="c.classno" :label="c.classname" ></el-option>
        </el-select>
      </el-form-item>

      <el-form-item>
        <el-button type="warning" @click="onSubmit">查询</el-button>
        <el-button type="primary" @click="onAdd">新增</el-button>
      </el-form-item>
    </el-form>


    <el-table :data="tableData" style="width: 100%">
      <el-table-column prop="id" label="编号"   />
      <el-table-column label="电子照片" >
        <template #default="scope">
          <img :src="'/api/student/'+scope.row.photo"  style="height: 50px;height: 50px">
        </template>
      </el-table-column>
      <el-table-column prop="studentname" label="名字"   />
      <el-table-column prop="gender" label="性别"   />
      <el-table-column prop="age" label="年龄"   />
      <el-table-column prop="classname" label="班级" />
      <el-table-column prop="address" label="地址" />

      <el-table-column  label="操作" >
        <template #default="scope">
          <el-button size="small" type="success" @click="toUpdate(scope.row)">编辑</el-button>
          <el-button size="small" type="danger" @click="toDel(scope.row.id)">删除</el-button>

          <el-upload

              :file-list="fileList"
              :show-file-list="false"
              class="upload-demo"
              :on-success="suceessFile"
              :action="'/api/stu/upload?id='+scope.row.id"
              multiple
              :limit="1"
          >
            <el-button type="primary" size="small">上传电子照</el-button>

          </el-upload>
        </template>
      </el-table-column>
    </el-table>


    <el-pagination
        background
        layout="prev, pager, next"

        :page-size="pageSize"
        :page-count="pages"
        @current-change="changePageNum"

        :total="total" />



  </div>

</template>

<style scoped lang="scss">

</style>

好博客就要一起分享哦!分享海报

此处可发布评论

评论(0展开评论

暂无评论,快来写一下吧

展开评论

您可能感兴趣的博客

客服QQ 1913284695