【VUE】案例:商场会员管理系统

news2024/12/23 18:00:56

编写vue+dfr实现对会员进行基本增删改查

1. drf项目初始化

  • 请求:

    POST
    http://127/0.0.0.1:8000/api/auth/
    {"username":"cqn", "password":"123"}
    
  • 返回:

    {"username":"cqn", "token":"fwjkfbj"}
    
  • 创建项目
    在这里插入图片描述

  • 项目目录结构
    在这里插入图片描述

1.1 安装并注册drf

  • pip install djangorestframework
  • settings.py
    INSTALLED_APPS = [
        ...
        'django.contrib.staticfiles',
        'api.apps.ApiConfig',
        'rest_framework',
    ]
    

1.2 创建数据库表并添加数据

  • models.py
    from django.db import models
    
    class UserInfo(models.Model):
        username = models.CharField(verbose_name="用户名", max_length=64)
        password = models.CharField(verbose_name="密码", max_length=64)
        token = models.CharField(verbose_name="token", max_length=64, null=True, blank=True)
    
  • makemigrations
  • migrate
  • 插入两条数据“root 123”,“cqn 123”

1.3 创建apiview文件

views/account.py

import uuid
from rest_framework import serializers
from rest_framework.views import APIView
from rest_framework.response import Response
from api import models

class AuthSerializer(serializers.Serializer):
    username = serializers.CharField(required=True)
    password = serializers.CharField(required=True)

class AuthView(APIView):
    def post(self, request):
        # 1. 获取用户提交数据 request.data = {"username": "xxx", "password": "...}
        # 2. 表单校验
        ser = AuthSerializer(data=request.data)
        if not ser.is_valid():
            return Response({"code": 1000, "msg": "校验失败", "detail": ser.errors})
        # 3. 数据库校验
        user_object = models.UserInfo.objects.filter(**ser.data).first()
        if not user_object:
            return Response({"code": -1, "msg": "用户名或密码错误"})
        token = uuid.uuid4()
        user_object.token = token
        user_object.save()
        # 4. 数据返回
        return Response({
            "code": 0,
            "data": {"id": user_object.id, "name": user_object.username, "token": user_object.token}
        })

1.4 添加url配置

urls.py

from django.urls import path
from api.views import account

urlpatterns = [
    path('api/auth/', account.AuthView.as_view()),
]

1.5 启动并验证

在这里插入图片描述

2. vue项目初始化

  • 创建项目
    在这里插入图片描述
  • 项目目录
    在这里插入图片描述

2.1 main.js注释全局样式

// import './assets/main.css'

2.2 App.vue

<script setup>
</script>

<template>
  <RouterView />
</template>

<style scoped>
</style>

2.3 views

LoginView.vue

<template>
  <div class="box">
    <p>
      用户名:
      <input type="text" placeholder="用户名" v-model="msg.username">
    </p>
    <p>
      密码:
      <input type="text" placeholder="密码" v-model="msg.password">
    </p>
    <p>
      <button @click="doLogin">登录</button>
    </p>
  </div>
</template>

<script setup>
import {ref} from "vue";
import {useRouter} from "vue-router";
import {userInfoStore} from "@/stores/user.js";
import _axios from "@/plugins/axios.js";

const msg = ref({
  username: "",
  password: ""
})
const router = useRouter()
const store = userInfoStore()

const doLogin = function () {
  // 1、获取数据
  console.log(msg.value)
  // 2、发送网络请求
  _axios.get("/api/v1/course/category/free/?courseType=free").then((res) => {
    console.log(res.data)
  })
  // 3、本地存储用户信息(登录凭证)
  // localStorage.setItem("name", msg.value.username)
  let info = {id: 1, name: msg.value.username, token: "ddsafhsjdfkj"}
  store.doLogin(info)
  // 3、跳转到首页
  router.push({name: "mine"})
}

</script>

<style scoped>
.box {
  width: 300px;
  margin: 100px auto;
}
</style>

AdminView.vue

<template>
  <div class="page-header">
    <div class="container">
      <RouterLink to="/admin/mine">我的</RouterLink>
      |
      <RouterLink to="/admin/order">订单</RouterLink>
      <div style="float:right;">
        <a>{{store.userName}}</a>
        <a @click="doLogout">退出1</a>
      </div>
    </div>
  </div>
  <div class="container">
    <RouterView/>
  </div>
</template>

<script setup>
import {useRouter} from "vue-router";
import {userInfoStore} from "@/stores/user.js";

const router = useRouter()
const store = userInfoStore()

function doLogout() {
  store.doLogout()
  router.push({name: "login"})
}
</script>

<style scoped>
body {
  margin: 0;
}

.page-header {
  height: 48px;
  background-color: cornflowerblue;
  line-height: 48px;
}

.page-header a {
  display: inline-block;
  padding: 0 10px;
  cursor: pointer;
}

.container {
  width: 980px;
  margin: 0 auto;
}

</style>

MineView.vue

<template>
  <h1>Mine</h1>
</template>

<script setup>
</script>

<style scoped>
</style>

OrderView.vue

<template>
  <h1>Order</h1>
</template>

<script setup>
</script>

<style scoped>
</style>

2.4 stores

user.js

import {ref, computed} from 'vue'
import {defineStore} from 'pinia'


export const userInfoStore = defineStore('userInfo', () => {
    const userString = ref(localStorage.getItem("info"))
    const userDict = computed(() => userString.value ? JSON.parse(userString.value) : null)
    const userId = computed(() => userDict.value ? userDict.value.id : null)
    const userName = computed(() => userDict.value ? userDict.value.name : null)
    const userToken = computed(() => userDict.value ? userDict.value.token : null)

    function doLogin(info) {
        localStorage.setItem("info", JSON.stringify(info))
        userString.value = JSON.stringify(info)

    }

    function doLogout() {
        localStorage.clear()
        userString.value = null
    }

    return {userId, userName, userToken, doLogin, doLogout}
})

2.5 router

index.js

import { createRouter, createWebHistory } from 'vue-router'
import {userInfoStore} from "@/stores/user.js";

const router = createRouter({
  history: createWebHistory(import.meta.env.BASE_URL),
  routes: [
    {
      path: '/login',
      name: 'login',
      component: () => import('../views/LoginView.vue')
    },
    {
      path: '/admin',
      name: 'admin',
      component: () => import('../views/AdminView.vue'),
      children: [
        {
          path: "",
          redirect: {name: "mine"}
        },
        {
          path: "mine",
          name: "mine",
          component: () => import('../views/MineView.vue')
        },
        {
          path: "order",
          name: "order",
          component: () => import('../views/OrderView.vue')
        }
      ]
    }
  ]
})
router.beforeEach(function (to,from,next) {
  // 1.访问登录页面,不需要登录就可以直接去查看
  if (to.name === "login") {
    next()
    return
  }
  // 2.检查用户登录状态,登录成功,继续往后走next();未登录,跳转至登录页面
  // let username = localStorage.getItem("name")
  const store = userInfoStore()
  if (!store.userId){
    next({name:"login"})
    return;
  }
  // 3.登录成功且获取到用户信息,继续向后访问
  next()
})

export default router

2.6 plugins

axios.js

import axios from "axios";

let config = {
    baseURL: "https://api.luffycity.com/",
    timeout: 20 * 1000
}

const _axios = axios.create(config)

_axios.interceptors.request.use(function (config){
    // console.log("请求前:", config)
    // 1. 去pinia中读取当前用户token
    // 2. 发送请求时携带token
    if(config.params){
        config.params["token"] = "djbfkjbdfkj"
    } else {
        config.params = {"token": "whejsabjdnfj"}
    }
    return config
})

export default _axios

2.7 安装并启动应用

  • sudo npm i
  • sudo npm i axios
  • sudo npm run dev
    在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

开源 AI 智能名片 O2O 商城小程序与抖音:品牌传播的新机遇与挑战

摘要&#xff1a;本文探讨了开源 AI 智能名片 O2O 商城小程序在品牌传播中的作用&#xff0c;以及与抖音平台相结合所带来的机遇与挑战。分析了抖音如何利用算法适配品牌调性为门店找到目标消费者&#xff0c;放大品牌势能&#xff0c;同时阐述了新品牌在抖音上进行品牌传播的优…

后端返回内容有换行标识,前端如何识别换行

<br/>的话 用 v-html \n 可以用css样式 white-space: pre-wrap 后端返回结果 前端

集成电路发展的两条主线

集成电路发展的两条主线&#xff0c; 1、增大晶圆尺寸&#xff0c;6、8、12英寸 晶圆尺寸不断增大&#xff0c;其设备要求不断增大。目前主流的8英寸&#xff0c;12英寸正在发展 2、芯片工艺制程不断减小

基于Hive和Hadoop的用电量分析系统

本项目是一个基于大数据技术的用电量分析系统&#xff0c;旨在为用户提供全面的电力消耗信息和深入的用电量分析。系统采用 Hadoop 平台进行大规模数据存储和处理&#xff0c;利用 MapReduce 进行数据分析和处理&#xff0c;通过 Sqoop 实现数据的导入导出&#xff0c;以 Spark…

quill富文本插入表格quill-better-table

使用quill-better-table插件&#xff0c;官网GitCode - 全球开发者的开源社区,开源代码托管平台 安装 首先quill-better-table插件&#xff0c;官网有写需要 quills v2.0.0-dev3 我这里使用的是 quills v2.0.0-dev4&#xff0c;自行安装 然后就是安装我们的插件 quill-bett…

【项目资料】项目售后服务方案(Word)

1.1 售后服务方案 概述 售后服务体系 售后服务流程 售后服务承诺 售后服务计划 技术支持响应承诺 售后服务响应时间 1.2 项目培训方案 项目培训体系 项目培训管理 培训目的与措施 项目培训安排 培训告知下达 培训人员贯彻 培训签到表 软件全套资料部分文档清单&#xff1a; 工作…

10款超好用的文档加密软件|2024企业文档加密软件分享

在信息安全日益受到重视的今天&#xff0c;选择合适的文档加密软件至关重要。以下是2024年值得关注的10款超好用的文档加密软件&#xff0c;帮助企业提升数据安全性。 1. Ping32文档加密软件 Ping32专注于文档加密&#xff0c;采用强大的AES加密技术&#xff0c;确保敏感信息在…

领夹式无线麦克风哪个品牌好,口碑最好的领夹麦克风品牌推荐

对于追求专业音频录制的创作者而言&#xff0c;无线领夹麦克风不仅是录制设备&#xff0c;更是表达自我的艺术工具。从市场反馈中&#xff0c;我们发现西圣、大疆、罗德等品牌深受消费者喜爱。不过我看事情不能只看一面&#xff0c;在市场繁荣的表象下&#xff0c;一些劣质产品…

单片机的两种看门狗原理解析——IWDG和WWDG

一、IWDG独立开门狗的主要性能 计时机制&#xff1a; 递减计数器 独立开门狗的初始频率&#xff1a; LSI低速内部时钟&#xff1a;RC震荡器&#xff0c;40kHz 独立开门狗是以LSI为初始频率的&#xff0c;所以独立开门狗的初始时钟频率取决与单片机本身&#xff0c;因此在使…

Charles(青花瓷)抓取https请求

文章目录 前言Charles&#xff08;青花瓷&#xff09;抓取https请求 前言 如果您觉得有用的话&#xff0c;记得给博主点个赞&#xff0c;评论&#xff0c;收藏一键三连啊&#xff0c;写作不易啊^ _ ^。   而且听说点赞的人每天的运气都不会太差&#xff0c;实在白嫖的话&…

【工具分享】Chimera勒索病毒解密工具

前言 Chimera勒索软件首次出现在2015年&#xff0c;最初是在德国被发现。该勒索软件不仅加密受害者的文件&#xff0c;还威胁如果不支付赎金&#xff0c;就会将被盗的数据公开发布。这种“双重勒索”策略使得Chimera在众多勒索软件中脱颖而出。Chimera通常通过钓鱼邮件传播&am…

第五部分:6---信号的递达

目录 信号的递达流程&#xff1a; 信号在什么时候递达&#xff1f; 用户态和内核态&#xff1a; 内核态、用户态在页表的映射关系&#xff1a; 操作系统如何得知当前执行状态是用户态还是内核态&#xff1f; 操作系统如何处理被捕捉的信号&#xff1f; 信号的递达流程&am…

Python PyQt5 在frame中生成多个QLabel控件和彻底销毁QLabel控件

文章目录 步骤 1: 创建主窗口和布局步骤 2: 添加QLabel到QFrame步骤 3: 销毁QLabel示例代码 在PyQt5中&#xff0c;在QFrame或任何其他容器控件中生成多个QLabel控件并通过一个标志位或方法来彻底销毁这些QLabel控件是相对直接的操作。以下是一个简单的示例&#xff0c;展示了如…

爬虫小案例:爬取豆瓣网TOP250的电影信息(内含面相对象源码、及详细教学)

爬虫案例二———爬取豆瓣网TOP250的电影信息&#xff0c;并存入MySQL数据库 前提准备 安装pymysql库 pip install pymysql -i https://pypi.tuna.tsinghua.edu.cn/simple Python连接MySQL数据库&#xff0c;并进行增删改查基本操作 连接数据库 """连接MyS…

坚果N1 Air高亮版对比当贝D6X高亮版:谁是2000元预算的投影仪王者?

当贝D6X高亮版新品升级&#xff0c;对于那些计划在这个时间点购买投影仪的用户来说&#xff0c;现在是个绝佳的时机&#xff01;特别是那些预算在两千元左右的&#xff0c;目前两千元左右的投影仪&#xff0c;无外乎两款产品&#xff0c;当贝D6X高亮版和坚果N1 Air高亮版&#…

David律所代理Beau Parsons的小狗插画图案版权维权,速排查下架

案件基本情况&#xff1a;起诉时间&#xff1a;2024-9-16案件号&#xff1a;2024-cv-08505原告&#xff1a;Beau Parsons原告律所&#xff1a;David起诉地&#xff1a;伊利诺伊州北部法院涉案商标/版权&#xff1a;原告品牌简介&#xff1a;Beau Parsons是一位来自澳大利亚的专…

AI情感陪伴新纪元:WT2605C语音芯片在成人用品中的创新应用

在探索成人用品领域的无限可能时&#xff0c;科技的每一次进步都为我们带来了前所未有的体验。而今&#xff0c;WT2605C AI语音芯片的引入&#xff0c;正悄然改变着这一传统行业的面貌&#xff0c;为成人用品赋予了全新的情感陪伴功能&#xff0c;开启了智能化、个性化的新时代…

鸿蒙开发(NEXT/API 12)【硬件(Pen Kit)】手写笔服务

Pen Kit&#xff08;手写笔服务&#xff09;是华为提供的一套手写套件&#xff0c;提供笔刷效果、笔迹编辑、报点预测、一笔成形和全局取色的功能。手写笔服务可以为产品带来优质手写体验&#xff0c;为您创造更多的手写应用场景。 目前Pen Kit提供了四种能力&#xff1a;手写…

Qt_网络编程

目录 1、Qt的UDP Socket 1.1 用Udp实现服务器 1.2 用Udp实现客户端 2、Qt的TCP Socket 2.1 用Tcp实现服务器 2.2 用Tcp实现客户端 3、Qt的HTTP 3.1使用Qt的HTTP 结语 前言&#xff1a; 网络协议是每个平台都必须遵守的&#xff0c;只是不同的平台所提供的网络API不…

[element-ui]记录对el-table表头样式的一些处理

1、表头换行 & 列表项换行 可用element-table组件自带的方法实现列标题换行的效果 2、小圆点样式