Django+Vue3前后端分离学习(五)(前端登录页面搭建)

1、如果需要使用组合式API,需要安装插件:

复制代码
npm install vite-plugin-vue-setup-extend --save-dev

在vite.config.js里配置:

首先导入:

复制代码
import VueSetupExtend from 'vite-plugin-vue-setup-extend'

添加:

2、创建login.vue

然后再index.js里添加:

然后修改根路由:

采用Hash方式:

在Vue中加载外部的css文件:

复制代码
<style scoped src="@/assets/css/login.css"></style>
<style scoped src="@/assets/iconfont/iconfont.css"></style>

图片的话,需要在<scripts>中当做对象一样导入进来

复制代码
 import login_image from "@/assets/image/login.png"

3、为了接收用户输入的邮箱和密码,在<scripts>里定义一个响应式对象:

引入

复制代码
import { reactive } from "vue";

let form=reactive({
    email:"",
    password:""
  })

然后在input里通过v-model绑定邮箱和密码:

给登录按钮添加点击事件:

邮箱正则表达式: let pwdRgx = /^[0-9a-zA-Z_-]{6,20}/

密码正则表达式:let emailRgx = /^([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+(.[a-zA-Z0-9])+/

采用axios库:

复制代码
npm install axios --save

或者设置版本号

npm install axios@1.6.8 --save

引入axios库:

复制代码
 import axios from "axios";

定义方法(后面有改进):

复制代码
     axios.post("http://127.0.0.1:8000/auth/login",{
       email:form.email,
       password:form.password
     }).then((res)=>{
        //then:代表是成功的情况(在这里,代表返回的状态码200)
       let data=res.data;
       let token=data.token;
       let user=data.user
       authStore.setUserToken(user,token);
       router.push({name:"frame"})

     }).catch((err)=>{
       //catch:代表失败的情况(在这里,代表返回的状态码是非200
       console.log(err.response.data.detail);
     })

数据的保存,放在stores文件夹里:

在stores里创建一个anth.js文件(可以把counter.js里的复制到auth.js里改造

复制代码
import { ref, computed } from 'vue'
import { defineStore } from 'pinia'

const USER_KEY = "OA_USER_KEY"
const TOKEN_KEY = "OA_TOKEN_KEY"


export const useAuthStore = defineStore('auth', () => {
  let _user = ref({})
  let _token = ref("")
  function setUserToken(user, token) {
    //保存到对象上(内存中)
    _user.value = user;
    _token.value = token;
    //存储到浏览器的localStorge中(硬盘上)
    localStorage.setItem(USER_KEY, JSON.stringify(user))
    localStorage.setItem(TOKEN_KEY, token)
  }

  function clearUserToken() {
    _user.value = {}
    _token.value = ""
    localStorage.removeItem(USER_KEY)
    localStorage.removeItem(TOKEN_KEY)
  }
  //计算属性
  let user = computed(() => {

    //在JS中
    //1、空对象{}:用if判断,会返回true Object.keys(_user.value).length==0
    //2、空字符串"":用if判断,会返回false
    if (Object.keys(_user.value).length == 0) {
      let user_str = localStorage.getItem(USER_KEY)
      if (user_str) {
        _user.value = JSON.parse(user_str)
      }
    }
    // if (!_user.value) {
    //   _user.value = localStorage.getItem(USER_KEY)
    // }
    return _user.value
  })
  let token = computed(() => {
    if (!_token.value) {
      let token_str = localStorage.getItem(TOKEN_KEY)
      if (token_str) {
        _token.value = token_str
      }
    }
    return _token.value
  })

  let is_logined = computed(() => {
    if (Object.keys(user.value).length > 0 && token.value) {
      return true;
    }
    return false;
  })
  return { setUserToken, user, token, is_logined, clearUserToken }
})

然后再login.vue中导入:

复制代码
  import { useAuthStore } from "@/stores/auth";

然后创建对象:

引入跳转 (router是路由跳转, route 是保存路由信息的):

复制代码
 import { useRouter } from "vue-router";

然后创建router对象:

设置路由跳转:

4、对axios 优化 ,封装:

在src文件夹下新建一个api文件夹,然后在其下面新建http.js

复制代码
import axios from "axios";

class Http {
  constructor() {
    this.instance = axios.create({
      baseURL: import.meta.env.VITE_BASE_URL,
      timeout: 6000,
    });
  }
  post(path, data) {
    // return this.instance.post(path,data)
    return new Promise(async (resolve, reject) => {
      // await:网络请求发送出去后,线程会挂起这个等待
      //等网络数据到达后,线程又会回到当前位置开始往后执行
      //如果在某个函数中使用了await,那么这个函数就必须要定义成async
      // axios底层也是用的Promise对象,在响应的状态码不是200时,就会调用reject,
      //调用reject的结果是,外层的函数会抛出异常
      try {
        let result = await this.instance.post(path, data)
        resolve(result.data)
      } catch (err) {
        //走到catch中,就说明状态码肯定不是200
        // let detail=err.response.data.detail;
        // err.result
        // err.response.data.detail
        reject(err.response.data.detail)
      }
    })
  }
  get(path, params) {
    return this.instance.get(path, params)
  }
}


export default new Http()

再创建一个专门写跟授权相关的API 在api文件夹下创建authHttp.js

复制代码
import http from "./http";

const login=(email,password)=>{
  const path='/auth/login'
  return http.post(path,{email,password})
}

export default{
  login
}

然后在login.vue里导入authHttp:

在login.vue里修改提交按钮方法:

复制代码
const OnSubmit=async ()=>{
    let pwdRgx = /^[0-9a-zA-Z_-]{6,20}/
    let emailRgx = /^([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+(.[a-zA-Z0-9])+/
    if (!(emailRgx.test(form.email)))
    {
        // alert('邮箱格式不满足')
        ElMessage.info('邮箱格式不满足!')
        return
    }
    if(!(pwdRgx.test(form.password)))
    {
      // alert('密码格式不满足')
      ElMessage.info('密码格式不满足!')
      return;
    }
 
    try{
      let data= await authHttp.login(form.email,form.password)
      let token=data.token;
      let user=data.user
      authStore.setUserToken(user,token);
      router.push({name:"frame"})

    }catch(detail){
      // alert(detail)
      ElMessage.error(detail)
    }
    
  }
相关推荐
虾球xz1 分钟前
CppCon 2018 学习:THE MOST VALUABLE VALUES
开发语言·c++·学习
掘金安东尼4 分钟前
前端周刊第421期(2025年7月1日–7月6日)
前端·面试·github
摸鱼仙人~6 分钟前
深入理解 classnames:React 动态类名管理的最佳实践
前端·react.js·前端框架
未来之窗软件服务8 分钟前
chrome webdrive异常处理-session not created falled opening key——仙盟创梦IDE
前端·人工智能·chrome·仙盟创梦ide·东方仙盟·数据调式
kymjs张涛9 分钟前
零一开源|前沿技术周报 #6
前端·ios·harmonyos
玲小珑12 分钟前
Next.js 教程系列(十)getStaticPaths 与动态路由的静态生成
前端·next.js
天天鸭18 分钟前
写个vite插件自动处理系统权限,降低99%重复工作
前端·javascript·vite
蓝婷儿23 分钟前
每天一个前端小知识 Day 23 - PWA 渐进式 Web 应用开发
前端
无奈何杨32 分钟前
CoolGuard风控中新增移动距离和移动速度指标
前端·后端
恋猫de小郭39 分钟前
Google I/O Extended :2025 Flutter 的现状与未来
android·前端·flutter