一个简单的前后端分离demo

功能类似于:
在这里插入图片描述

一,安装及简单配置前端vue开发环境与项目

1,下载并安装node.js

Node.js

C:\Users\PC>node -v
v12.18.3

2,安装淘宝镜像

C:\Users\PC>npm install -g cnpm --registry=HTTPS://registry.npm.taobao.org
npm WARN deprecated request@2.88.2: request has been deprecated, see https://github.com/request/request/issues/3142
npm WARN deprecated har-validator@5.1.5: this
C:\Users\PC\AppData\Roaming\npm\cnpm -> C:\Users\PC\AppData\Roaming\npm\node_modules\cnpm\bin\cnpm
+ cnpm@6.1.1
added 685 packages from 970 contributors in 28.127s

3,安装vue.js脚手架

C:\Users\PC>cnpm install --global vue-cli
Downloading vue-cli to C:\Users\PC\AppData\Roaming\npm\node_modules\vue-cli_tmp
Copying C:\Users\PC\AppData\Roaming\npm\node_modules\vue-cli_tmp\_vue-cli@2.9.6@vue-cli to C:\Users\PC\AppData\Roaming\npm\node_modules\vue-cli
Installing vue-cli's dependencies to C:\Users\PC\AppData\Roaming\npm\node_modules\vue-cli/node_modules
[1/20] commander@^2.9.0 installed at node_modules\_commander@2.20.3@commander
[2/20] async@^2.4.0 installed at node_modules\_async@2.6.3@async
[3/20] consolidate@^0.14.0 installed at node_modules\_consolidate@0.14.5@consolidate
[4/20] minimatch@^3.0.0 installed at node_modules\_minimatch@3.0.4@minimatch
[5/20] rimraf@^2.5.0 existed at node_modules\_rimraf@2.7.1@rimraf
[6/20] multimatch@^2.1.0 installed at node_modules\_multimatch@2.1.0@multimatch
[7/20] ora@^1.3.0 installed at node_modules\_ora@1.4.0@ora
[8/20] handlebars@^4.0.5 installed at node_modules\_handlebars@4.7.6@handlebars
[9/20] semver@^5.1.0 installed at node_modules\_semver@5.7.1@semver
[10/20] chalk@^2.1.0 installed at node_modules\_chalk@2.4.2@chalk
[11/20] coffee-script@1.12.7 existed at node_modules\_coffee-script@1.12.7@coffee-script
[12/20] read-metadata@^1.0.0 installed at node_modules\_read-metadata@1.0.0@read-metadata
[13/20] uid@0.0.2 installed at node_modules\_uid@0.0.2@uid
[14/20] user-home@^2.0.0 installed at node_modules\_user-home@2.0.0@user-home
[15/20] tildify@^1.2.0 installed at node_modules\_tildify@1.2.0@tildify
[16/20] metalsmith@^2.1.0 installed at node_modules\_metalsmith@2.3.0@metalsmith
[17/20] validate-npm-package-name@^3.0.0 installed at node_modules\_validate-npm-package-name@3.0.0@validate-npm-package-name
[18/20] download-git-repo@^1.0.1 installed at node_modules\_download-git-repo@1.1.0@download-git-repo
[19/20] request@^2.67.0 installed at node_modules\_request@2.88.2@request
[20/20] inquirer@^6.0.0 installed at node_modules\_inquirer@6.5.2@inquirer
deprecate metalsmith@2.3.0 › gray-matter@2.1.1 › coffee-script@^1.12.4 CoffeeScript on NPM has moved to "coffeescript" (no hyphen)
deprecate request@^2.67.0 request has been deprecated, see https://github.com/request/request/issues/3142
deprecate request@2.88.2 › har-validator@~5.1.3 this library is no longer supported
Recently updated (since 2020-08-28): 3 packages (detail see file C:\Users\PC\AppData\Roaming\npm\node_modules\vue-cli\node_modules\.recently_updates.txt)
  2020-09-03
    → download-git-repo@1.1.0 › download@5.0.3 › decompress@4.2.1 › decompress-tar@4.1.1 › tar-stream@1.6.2 › bl@^1.0.0(1.2.3) (17:52:16)
  2020-08-31
    → handlebars@4.7.6 › uglify-js@^3.1.4(3.10.3) (00:58:49)
    → request@2.88.2 › har-validator@5.1.5 › ajv@6.12.4 › uri-js@^4.2.2(4.4.0) (03:04:37)
All packages installed (233 packages installed from npm registry, used 7s(network 6s), speed 797.88kB/s, json 220(472.43kB), tarball 4.54MB)
[vue-cli@2.9.6] link C:\Users\PC\AppData\Roaming\npm\vue@ -> C:\Users\PC\AppData\Roaming\npm\node_modules\vue-cli\bin\vue
[vue-cli@2.9.6] link C:\Users\PC\AppData\Roaming\npm\vue-init@ -> C:\Users\PC\AppData\Roaming\npm\node_modules\vue-cli\bin\vue-init
[vue-cli@2.9.6] link C:\Users\PC\AppData\Roaming\npm\vue-list@ -> C:\Users\PC\AppData\Roaming\npm\node_modules\vue-cli\bin\vue-list

4,创建并运行vue项目

F:\PythonProjects\web\goods>vue init webpack-simple demo1
? Project name demo1
? Project description A Vue.js project
? Author
? License MIT
? Use sass? No

F:\PythonProjects\web\goods>cnpm install
√ All packages installed (723 packages installed from npm registry, used 26s(network 26s), speed 628.15kB/s, json 635(1.61MB), tarball 14.18MB)

在这里插入图片描述

F:\PythonProjects\web\python django web dianxing\goods\demo1>npm run dev

> demo1@1.0.0 dev F:\PythonProjects\web\goods\demo1
> cross-env NODE_ENV=development webpack-dev-server --open --hot

Project is running at http://localhost:8080/
webpack output is served from /dist/
404s will fallback to /index.html
{ parser: "babylon" } is deprecated; we now treat it as { parser: "babel" }.

在这里插入图片描述

5,前端内容

在src/App.vue中添加:
1,HTML:

<template>
  <div id="app">
    <div class="all">
      <div class="one">
        <div class="onetype" v-for="(item,index) in one" :key="index">
          <b>{{one[index]}}</b>
        </div>
      </div>
      <div class="twothreefour">
        <div class="two">
          <div class="twotype"
          v-for="(item,index) in two" :key="index"
           @mouseenter="open(index)">
            <b>{{two[index]}}</b>
          </div>
        </div>
        <div class="threefour" v-if="flag"
           @mouseleave="close()">
          <div class="threefourtype" v-for="(item,index) in three" :key="index">
            <span class="three">{{three[index]}}</span>
           <span class="four" v-for="(item4,index4) in four" :key="index4">{{four[index4]}}</span>
          </div>
        </div>
      </div>
    </div>
  </div>

</template>

2,JavaScript:

<script>
export default {
  name: 'app',
  data () {
    return {
      one:['一级类目','一级类目','一级类目','一级类目','一级类目'],
      two:['二级类目1','二级类目2','二级类目3','二级类目4','二级类目5'],
      three:[],
      four:['四级类目','四级类目','四级类目','四级类目','四级类目'],
      flag:false
    }
  },
  methods: {
    open(index){
      var index=index+1;
      var i=index+"";
      this.three=['三级目录'+i,'三级目录'+i,'三级目录'+i,'三级目录'+i,'三级目录'+i]
      this.flag=true
    },
    close(){
      this.flag=false
    }
  },
}
</script>

3,css:

<style>
*{
  /* 样式初始化 */
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}
.all{
  /* 将整个导航栏组件做整体设置 */
  /*宽度占浏览器80%,高度400px;背景灰色;上外边距50px; 左右居中*/
  /* 设置为flex弹性盒子,并且定义为高度不够自动折行模式,用于横向排列子元素 */
  width: 80%;
  height: 400px;
  background:#eee;
  margin: 50px auto;
  display: -webkit-flex; /* Safari */
  display: flex;
  flex-wrap: wrap;
}
.one{
  /* 设置一级类目所占地区的样式,宽度占满all盒子的100% */
  width: 100%;
  height: 50px;
  background: #FF8888;
  display: flex;
  display: -webkit-flex; /* Safari */
  flex-wrap: wrap;
  /* 弹性盒子内部的子元素都均匀排列成一横排,并且左右两边都留有一定空隙 */
  justify-content: space-around;
}
.onetype{
  width: 20%;
  height: 50px;
  line-height: 50px;
  text-align: center;
}
.onetype:hover{
  background-color:chocolate;
  color: #eee;
}
.twothreefour{
  /* 盛放二三四级目录的盒子 */
  width: 100%;
  height: 350px;
  background: #66FF66;
  display: -webkit-flex; /* Safari */
  display: flex;
  flex-wrap: wrap;
  /* 弹性盒子内部的子元素都均匀排列成一横排,并且左右两边都不留空隙 */
  justify-content: space-between;
}
.two{
  /* 设置盛放二级类目的弹性盒子 */
  width: 15%;
  height: 100%;
  background: #77FFCC;
  display: -webkit-flex; /* Safari */
  display: flex;
  /* 弹性盒子内部的子元素从上到下排成一列 */
  flex-direction: column;
}
.twotype{
  width: 100%;
  height: 40px;
  line-height: 40px;
  text-align: center;
  background: #EEFFBB;
}
.twotype:hover{
  background-color:black;
  color: #eee;
}
.threefour{
  width: 40%;
  margin-right: 45%;
  height: 100%;
  background: #33FFDD;
  display: -webkit-flex; /* Safari */
  display: flex;
  flex-direction: column;
}
.threefourtype{
  margin: 10px auto;
}
.three{
  font-family: 微软雅黑, 黑体;
  font-size: 16px;
  font-weight: 800;
}
.four{
  font-family: 宋体;
  font-size: 12px;
  font-weight: 400;
}
</style>

在这里插入图片描述

二,前后端分离

前端vue.js将请求通过API发送给后端,后端进行请求处理并作出请求响应,前端获取相应数据后赋值给data从而更改前端页面内容。

三,后端项目

1,创建开发环境及项目

项目目录结构如下:
在这里插入图片描述
安装DRF等依赖包:

pip install Djangorestframework markdown Django-filter pillow Django-guardian coreapi

2,创建商品类别模型并添加数据

from django.db import models
from datetime import datetime

# Create your models here.
class Type1(models.Model):
    """
    一级类目
    """
    name = models.CharField(max_length=10, default="", verbose_name="类目名")
    add_time = models.DateTimeField(default=datetime.now, verbose_name='添加时间')

    class Meta:
        verbose_name = '商品类别'
        verbose_name_plural = verbose_name

    def __str__(self):
        return self.name


class Type2(models.Model):
    """
    二级类目
    """
    parent = models.ForeignKey(Type1, verbose_name="父级类别",
                               null=True, blank=True, on_delete=models.CASCADE)
    name = models.CharField(max_length=10, default="", verbose_name="类目名")
    add_time = models.DateTimeField(default=datetime.now, verbose_name='添加时间')

    class Meta:
        verbose_name = '商品类别2'
        verbose_name_plural = verbose_name

    def __str__(self):
        return self.name


class Type3(models.Model):
    """
    三级类目
    """
    parent = models.ForeignKey(Type2, verbose_name="父级类别",
                               null=True, blank=True, on_delete=models.CASCADE)
    name = models.CharField(max_length=10, default="", verbose_name="类目名")
    add_time = models.DateTimeField(default=datetime.now, verbose_name='添加时间')

    class Meta:
        verbose_name = '商品类别3'
        verbose_name_plural = verbose_name

    def __str__(self):
        return self.name


class Type4(models.Model):
    """
    四级类目
    """
    parent = models.ForeignKey(Type3, verbose_name="父级类别",
                               null=True, blank=True, on_delete=models.CASCADE)
    name = models.CharField(max_length=10, default="", verbose_name="类目名")
    add_time = models.DateTimeField(default=datetime.now, verbose_name='添加时间')

    class Meta:
        verbose_name = '商品类别4'
        verbose_name_plural = verbose_name

    def __str__(self):
        return self.name

数据迁移并添加一些数据到表中。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3,实现序列化

app01/serializers.py:
from rest_framework import serializers  
from .models import Type1, Type2, Type3, Type4  


class Type1ModelSerializer(serializers.ModelSerializer):
    class Meta:
        model = Type1
        fields = "__all__"


class Type2ModelSerializer(serializers.ModelSerializer):
    class Meta:
        model = Type2
        fields = "__all__"


class Type3ModelSerializer(serializers.ModelSerializer):
    class Meta:
        model = Type3
        fields = "__all__"


class Type4ModelSerializer(serializers.ModelSerializer):
    class Meta:
        model = Type4
        fields = "__all__"
app01/views.py:
from app01.serializers import Type1ModelSerializer, Type2ModelSerializer
from app01.serializers import Type3ModelSerializer, Type4ModelSerializer
from app01.models import Type1, Type2, Type3, Type4
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.renderers import JSONRenderer, BrowsableAPIRenderer


# Create your views here.
class Type1View(APIView):
    """
    all Type1
    """
    renderer_classes = [JSONRenderer]

    def get(self, request, format=None):
        types = Type1.objects.all()
        types_serializer = Type1ModelSerializer(types, many=True)
        return Response(types_serializer.data)


class Type2View(APIView):
    """
    all Type2
    """
    renderer_classes = [JSONRenderer]

    def get(self, request, format=None):
        types = Type2.objects.all()
        types_serializer = Type2ModelSerializer(types, many=True)
        return Response(types_serializer.data)


class Type3View(APIView):
    """
    all Type3
    """
    renderer_classes = [JSONRenderer]

    def get(self, request, format=None):
        types = Type3.objects.all()
        types_serializer = Type3ModelSerializer(types, many=True)
        return Response(types_serializer.data)


class Type4View(APIView):
    """
    all Type4
    """
    renderer_classes = [JSONRenderer]

    def get(self, request, format=None):
        types = Type4.objects.all()
        types_serializer = Type4ModelSerializer(types, many=True)
        return Response(types_serializer.data)

4,路由

app01/urls.py:
from django.urls import path
from app01.views import *

urlpatterns = [
    path('type1/', Type1View.as_view(), name='type1'),
    path('type2/', Type2View.as_view(), name='type2'),
    path('type3/', Type3View.as_view(), name='type3'),
    path('type4/', Type4View.as_view(), name='type4'),
]

demo2/urls.py:
from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('api/', include("app01.urls"), name='api')
]

四,前后端联合调试

1,给前端添加网络请求模块

F:\PythonProjects\web\python django web dianxing\goods\demo1>cnpm install axios --save
√ Installed 1 packages
√ Linked 1 latest versions
√ Run 0 scripts
√ All packages installed (1 packages installed from npm registry, used 2s(network 2s), speed 48.13kB/s, json 2(9.1kB), tarball 92.65kB)

2,改写前端内容

<template>
  <div id="app">
    <div class="all">
      <div class="one">
        <div class="onetype" v-for="(item,index) in one" :key="index">
          <b>{{one[index].name}}</b>
        </div>
      </div>
      <div class="twothreefour">
        <div class="two">
          <div class="twotype" 
          v-for="(item,index) in two" :key="index"
           @mouseenter="open(index)">
            <b>{{two[index].name}}</b>
          </div>
        </div>
        <div class="threefour" v-if="flag"
           @mouseleave="close()">
          <div class="threefourtype" v-for="(item,index) in three1" :key="index">
            <span class="three">{{three1[index]}}</span>
            <span class="four" v-for="(item4,index4) in four1" :key="index4">
{{four1[index4]}}&nbsp;</span>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>
<script>
import Axios from 'axios';
export default {
  name: 'app',
  data () {
    return {
      one:[],
      two:[],
      three:[],
      four:[],
      flag:false,
      three1:[],
      four1:[]
    }
  },
  methods: {
    getData(){
      const api='http://127.0.0.1:8000/';
      var api1=api+'api/type1/';
      var api2=api+'api/type2/';
      var api3=api+'api/type3/';
      var api4=api+'api/type4/';
      var type1=[];
      var type2=[];
      var type3=[];
      var type4=[];
      Axios.get(api1)
      .then(function (response) {
      // console.log(response);
      for(var i=0;i<response.data.length;i++){
        // console.log(response.data[i])
        type1.push(response.data[i])
      }
      // console.log(type1)
      })
      .catch(function (error) {
      console.log(error);
      });
      this.one=type1;
      Axios.get(api2)
      .then(function (response) {
      // console.log(response);
      for(var i=0;i<response.data.length;i++){
        // console.log(response.data[i])
        type2.push(response.data[i])
      }
      // console.log(type2)
      })
      .catch(function (error) {
      console.log(error);
      });
      this.two=type2;
      Axios.get(api3)
      .then(function (response) {
      // console.log(response);
      for(var i=0;i<response.data.length;i++){
        // console.log(response.data[i])
        type3.push(response.data[i])
      }
      // console.log(type3)
      })
      .catch(function (error) {
      console.log(error);
      });
      this.three=type3;
      Axios.get(api4)
      .then(function (response) {
      // console.log(response);
      for(var i=0;i<response.data.length;i++){
        // console.log(response.data[i])
        type4.push(response.data[i])
      }
      // console.log(type4)
      })
      .catch(function (error) {
      console.log(error);
      });
      this.four=type4;
      // console.log(this.one)
      // console.log(this.two)
      // console.log(this.three)
      // console.log(this.four)
},
    open(index){
      // console.log(this.two[index].id)
      var temp=[]
      for(var i=0;i<this.three.length;i++){
        if(this.three[i].parent===index+1){
          temp.push(this.three[i].name)
        }
      }
      console.log(temp)
      this.three1=temp;
      var temp4=[]
      for(var j=0;j<this.four.length;j++){
        temp4.push(this.four[j].name)
      }
      this.four1=temp4
      this.flag=true
    },
    close(){
      this.flag=false
    }
  },
  mounted() {
    this.getData()
  },
}
</script>

css保留

3,后端设置跨域访问

略。

4,分别启动前后端

在这里插入图片描述
在这里插入图片描述

  • 四级菜单并未进行分类,可仿照三级菜单改进。
  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
很高兴为你提供一个Django+Vue3+ElementPlus前后端分离demo。 ## 后端部分 首先,我们需要创建一个Django项目。在命令行中输入以下命令: ``` django-admin startproject project_name ``` 然后,我们需要创建一个应用程序。在命令行中输入以下命令: ``` python manage.py startapp app_name ``` 接下来,我们需要安装一些必要的库。在命令行中输入以下命令: ``` pip install djangorestframework django-cors-headers ``` 接下来,我们需要在`settings.py`文件中添加以下代码: ```python INSTALLED_APPS = [ ... 'rest_framework', 'corsheaders', 'app_name', ] MIDDLEWARE = [ ... 'corsheaders.middleware.CorsMiddleware', 'django.middleware.common.CommonMiddleware', ] CORS_ORIGIN_ALLOW_ALL = True ``` 现在,我们已经完成了后端部分的设置。我们可以开始编写API。 在`app_name`中创建一个名为`api.py`的文件,并编写以下代码: ```python from rest_framework.decorators import api_view from rest_framework.response import Response @api_view(['GET']) def hello_world(request): return Response({"message": "Hello, World!"}) ``` 这是一个简单的API,当我们向`/api/hello`发送GET请求时,它将返回一个JSON响应,其中包含“Hello, World!”消息。 最后,在`urls.py`文件中添加以下代码: ```python from django.urls import path from . import api urlpatterns = [ path('api/hello', api.hello_world), ] ``` 现在,我们已经完成了后端部分的设置。我们可以在终端中运行`python manage.py runserver`命令来启动服务器。 ## 前端部分 首先,我们需要安装Vue CLI。在命令行中输入以下命令: ``` npm install -g @vue/cli ``` 然后,我们需要创建一个Vue项目。在命令行中输入以下命令: ``` vue create project_name ``` 接下来,我们需要安装ElementPlus。在命令行中输入以下命令: ``` npm i element-plus -S ``` 接下来,我们需要在`main.js`文件中添加以下代码: ```javascript import { createApp } from 'vue' import App from './App.vue' import ElementPlus from 'element-plus' import 'element-plus/lib/theme-chalk/index.css' createApp(App).use(ElementPlus).mount('#app') ``` 现在,我们已经完成了前端部分的设置。我们可以开始编写页面。 在`src`中创建一个名为`HelloWorld.vue`的文件,并编写以下代码: ```vue <template> <div> <h1>{{ message }}</h1> </div> </template> <script> export default { data() { return { message: '' } }, created() { fetch('http://localhost:8000/api/hello') .then(response => response.json()) .then(data => this.message = data.message) } } </script> ``` 这是一个简单的页面,它将从我们的API中获取消息并显示在页面上。 最后,在`App.vue`文件中添加以下代码: ```vue <template> <HelloWorld /> </template> <script> import HelloWorld from './components/HelloWorld.vue' export default { components: { HelloWorld } } </script> ``` 现在,我们已经完成了前端部分的设置。我们可以在终端中运行`npm run serve`命令来启动前端服务器。 现在,我们可以在浏览器中访问`http://localhost:8080`,应该可以看到一个页面,其中包含“Hello, World!”消息。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值