【VUE】会员管理(增删改查)

前端

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: "home"}
        },
        {
          path: "home",
          name: "home",
          component: () => import('../views/HomeView.vue')
        },
        {
          path: "vip",
          name: "vip",
          component: () => import('../views/VipView.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

views/VipView.vue

<template>
  <h1>会员管理</h1>
  <button @click="doEdit">编辑</button>
  <table border="1">
    <thead>
    <tr>
      <th>ID</th>
      <th>姓名</th>
      <th>级别</th>
      <th>积分</th>
      <th>操作</th>
    </tr>
    </thead>
    <tbody>
    <tr v-for="(item,idx) in dataList">
      <td>{{ item.id }}</td>
      <td>{{ item.name }}</td>
      <td>{{ item.level_text }}</td>
      <td>{{ item.score }}</td>
      <td>
        <a>编辑</a>
        |
        <a>删除</a>
      </td>
    </tr>
    </tbody>
  </table>

  <div v-show="dialog" class="mask"></div>
  <div v-show="dialog" class="dialog">
    <input type="text"/>
    <p>
      <button>保存</button>
      <button @click="dialog=false">取消</button>
    </p>
  </div>
</template>

<script setup>
import {ref} from "vue";

const dataList = ref([{id: 1, name: "cc", age: 18, level_text: "SVIP", score: 1000}])
const dialog = ref(false)

function doEdit() {
  dialog.value = true
}
</script>

<style scoped>
.mask {
  position: fixed;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
  background-color: black;
  opacity: 0.8;
  z-index: 998;
}

.dialog {
  position: fixed;
  top: 200px;
  right: 0;
  left: 0;
  width: 400px;
  height: 300px;
  background-color: white;
  margin: 0 auto;
  z-index: 9999;
}
</style>

后端

GET     http://127.0.0.1:8000/api/vip/          -> 会员列表
POST    http://127.0.0.1:8000/api/vip/          -> 新增会员(请求体中传入数据)
DELETE  http://127.0.0.1:8000/api/vip/会员ID/    -> 删除会员
PUT     http://127.0.0.1:8000/api/vip/会员ID/    -> 更新会员(请求体中传入数据)

urls.py

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

urlpatterns = [
    path('api/auth/', account.AuthView.as_view()),
    path('api/vip/', vip.VipView.as_view()),
    path('api/vip/<int:vid>/', vip.VipDetailView.as_view()),
]

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)

class Vip(models.Model):
    """ 会员管理 """
    name = models.CharField(verbose_name="用户名", max_length=32)
    level = models.IntegerField(verbose_name="级别", choices=[(1, "VIP"), (2, "SVIP"), (3, "SSVIP")])
    score = models.IntegerField(verbose_name="积分")

views/vip.py

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


class VipSerializers(serializers.ModelSerializer):
    level_text = serializers.CharField(source="get_level_display", read_only=True)

    class Meta:
        model = models.Vip
        fields = "__all__"


class VipView(APIView):
    def get(self, request):
        # 会员列表
        queryset = models.Vip.objects.all().order_by("id")
        ser = VipSerializers(instance=queryset, many=True)
        return Response({"code": 0, "data": ser.data})

    def post(self, request):
        # 新增
        pass


class VipDetailView(APIView):
    def delete(self, request, vid):
        # 删除
        pass

    def put(self, request, vid):
        # 修改
        pass

前端:VipView.vue

<template>
  <h1>会员管理</h1>
  <button @click="doEdit">编辑</button>
  <table border="1">
    <thead>
    <tr>
      <th>ID</th>
      <th>姓名</th>
      <th>级别</th>
      <th>积分</th>
      <th>操作</th>
    </tr>
    </thead>
    <tbody>
    <tr v-for="(item,idx) in dataList">
      <td>{{ item.id }}</td>
      <td>{{ item.name }}</td>
      <td>{{ item.level_text }}</td>
      <td>{{ item.score }}</td>
      <td>
        <a>编辑</a>
        |
        <a>删除</a>
      </td>
    </tr>
    </tbody>
  </table>

  <div v-show="dialog" class="mask"></div>
  <div v-show="dialog" class="dialog">
    <input type="text"/>
    <p>
      <button>保存</button>
      <button @click="dialog=false">取消</button>
    </p>
  </div>
</template>

<script setup>
import {ref, onMounted} from "vue";
import _axios from "@/plugins/axios.js";

const dataList = ref([{id: 1, name: "cc", age: 18, level_text: "SVIP", score: 1000}])
const dialog = ref(false)

onMounted(function (){
  _axios.get("/api/vip/").then((res) => {
    console.log(res.data)
    dataList.value = res.data.data
  })
})
function doEdit() {
  dialog.value = true
}
</script>

<style scoped>
.mask {
  position: fixed;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
  background-color: black;
  opacity: 0.8;
  z-index: 998;
}

.dialog {
  position: fixed;
  top: 200px;
  right: 0;
  left: 0;
  width: 400px;
  height: 300px;
  background-color: white;
  margin: 0 auto;
  z-index: 9999;
}
</style>

删除

vip.py

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


class VipSerializers(serializers.ModelSerializer):
    level_text = serializers.CharField(source="get_level_display", read_only=True)

    class Meta:
        model = models.Vip
        fields = "__all__"


class VipView(APIView):
    def get(self, request):
        # 会员列表
        queryset = models.Vip.objects.all().order_by("id")
        ser = VipSerializers(instance=queryset, many=True)
        return Response({"code": 0, "data": ser.data})

    def post(self, request):
        # 新增
        pass


class VipDetailView(APIView):
    def delete(self, request, vid):
        # 删除
        models.Vip.objects.filter(id=vid).delete()
        return Response({"code": 0})

    def put(self, request, vid):
        # 修改
        pass

cors.py

from django.utils.deprecation import MiddlewareMixin


class CorsMiddleware(MiddlewareMixin):
    def process_response(self, request, response):
        response['Access-Control-Allow-Origin'] = "*"
        response['Access-Control-Allow-Headers'] = "*"
        response['Access-Control-Allow-Methods'] = "*"
        return response

前端
VipView.vue

<template>
  <h1>会员管理</h1>
  <button @click="doEdit">新增</button>
  <table border="1">
    <thead>
    <tr>
      <th>ID</th>
      <th>姓名</th>
      <th>级别</th>
      <th>积分</th>
      <th>操作</th>
    </tr>
    </thead>
    <tbody>
    <tr v-for="(item,idx) in dataList">
      <td>{{ item.id }}</td>
      <td>{{ item.name }}</td>
      <td>{{ item.level_text }}</td>
      <td>{{ item.score }}</td>
      <td>
        <a>编辑</a>
        |
        <button @click="doDelete(item.id, idx)">删除</button>
      </td>
    </tr>
    </tbody>
  </table>

  <div v-show="dialog" class="mask"></div>
  <div v-show="dialog" class="dialog">
    <input type="text"/>
    <p>
      <button>保存</button>
      <button @click="dialog=false">取消</button>
    </p>
  </div>
</template>

<script setup>
import {ref, onMounted} from "vue";
import _axios from "@/plugins/axios.js";

const dataList = ref([{id: 1, name: "cc", age: 18, level_text: "SVIP", score: 1000}])
const dialog = ref(false)

onMounted(function () {
  _axios.get("/api/vip/").then((res) => {
    console.log(res.data)
    dataList.value = res.data.data
  })
})

function doEdit() {
  dialog.value = true
}

function doDelete(vid, idx) {
  _axios.delete(`/api/vip/${vid}/`).then((res) => {
    // console.log(res.data)
    if (res.data.code === 0) {
      dataList.value.splice(idx, 1)
    }
  })
}
</script>

<style scoped>
.mask {
  position: fixed;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
  background-color: black;
  opacity: 0.8;
  z-index: 998;
}

.dialog {
  position: fixed;
  top: 200px;
  right: 0;
  left: 0;
  width: 400px;
  height: 300px;
  background-color: white;
  margin: 0 auto;
  z-index: 9999;
}
</style>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值