一个简单的前后端分离demo

导读:本篇文章讲解 一个简单的前后端分离demo,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com

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

一,安装及简单配置前端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,分别启动前后端

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

  • 四级菜单并未进行分类,可仿照三级菜单改进。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/98141.html

(0)
小半的头像小半

相关推荐

极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!