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)
    }
    
  }
相关推荐
行然梦实8 分钟前
学习日记_20241110_聚类方法(K-Means)
学习·kmeans·聚类
马船长13 分钟前
制作图片木马
学习
秀儿还能再秀25 分钟前
机器学习——简单线性回归、逻辑回归
笔记·python·学习·机器学习
WCF向光而行30 分钟前
Getting accurate time estimates from your tea(从您的团队获得准确的时间估计)
笔记·学习
涔溪34 分钟前
Ecmascript(ES)标准
前端·elasticsearch·ecmascript
榴莲千丞44 分钟前
第8章利用CSS制作导航菜单
前端·css
奔跑草-1 小时前
【前端】深入浅出 - TypeScript 的详细讲解
前端·javascript·react.js·typescript
wang09071 小时前
工作和学习遇到的技术问题
学习
羡与1 小时前
echarts-gl 3D柱状图配置
前端·javascript·echarts
guokanglun1 小时前
CSS样式实现3D效果
前端·css·3d