基於Vue和Django搭建前後端分離項目

前言

最近公司要做一個系統,需要前後端分離,後端使用Django,前端使用Vue,因爲之前主要做的是後端開發,前端只會寫一寫簡單的,Vue只會綁定數據,至於Vue怎麼與Django結合還是第一次接觸,所以去看了一些資料和官方文檔,接下來就簡單介紹一下流程吧!

創建Django項目

django-admin startproject test_demo
cd test_demo 	
django-admin startapp backend

到這裏我們已經建好了一個Django的初期項目。

安裝Vue

接下來我們需要安裝前端需要的東西,這裏我們使用npm安裝vue,所以需要先安裝node.js(下載點擊這裏),安裝提示一步一步執行完就好了。

npm install vue
npm install -g vue-cli

若沒有安裝webpack,則先安裝webpack:

npm install -g webpack

創建Vue項目

首先,我們進入到我們的Django項目,確保我們處在跟app同一級,然後使用:

vue-init webpack firstvue

界面中會出現很多需要動手選擇的,如下
Project name:(默認回車鍵)
Project description:(默認回車鍵)
Auther:(輸入自己的名字,隨意)
輸入之後就一直回車,直到出現是否要安裝vue-router,這個我們在項目要用到,所以就輸入y 回車,
執行完後,我們的整個項目結構應該是這樣
在這裏插入圖片描述
現在我們要安裝前後端分離的必要依賴包。
axios是vue官方推薦的前後端互通信息的插件

npm install axios

至此,vue部分差不多結束了,再來介紹一下vue項目結構:
在這裏插入圖片描述
在這裏插入圖片描述
現在我們先把後端接口調好和相關第三方庫安裝好。

settings.py配置

INSTALLED_APPS = [
    ...
    'backend', # app
    'corsheaders', # pip install django-cors-headers 這個是爲了防止跨域,具體請另查資料,我這裏就不贅述了。
    'rest_framework', # pip install djangorestframework 方便我們寫後端接口
]
MIDDLEWARE = [
    ...
    'django.contrib.sessions.middleware.SessionMiddleware',
    'corsheaders.middleware.CorsMiddleware', # 這個的導入不能太靠後,因爲中間件也有先後順序的加載
    'django.middleware.common.CommonMiddleware',
   ...
]
TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [
            'firstvue/dist',
        ],
        ...
    },
]
# 支持跨域配置開始
CORS_ALLOW_CREDENTIALS = True

CORS_ALLOW_CREDENTIALS = True # 允許攜帶cookie
CORS_ORIGIN_WHITELIST = ( # 設置白名單
    'http://127.0.0.1:8080',
    'http://localhost:8080',
)
CORS_ALLOW_METHODS = ( # 設置請求方法
    'DELETE',
    'GET',
    'POST',
    'OPTIONS',
    'PATCH',
    'PUT',
    'VIEW',
)
CORS_ALLOW_HEADERS = ( # 設置請求頭的內容
    'XMLHttpRequest',
    'X_FILENAME',
    'accept-encoding',
    'authorization',
    'content-type',
    'dnt',
    'origin',
    'user-agent',
    'x-csrftoken',
    'x-request-with',
    'Pragma',
)
# 支持跨域配置結束
STATICFILES_DIRS = [
    os.path.join(BASE_DIR,"firstvue/dist/static") # 這個是我們收集靜態文件的路徑
]

我們先把我們的前端模板導入到我們的後端,也就是我們前後端首頁的頁面,這裏不需要寫什麼路勁,只需要將firstvue下的index.html寫在這裏就好,系統自己回去找到位置。

test_demo\test_demo\urls.py

from  django.views.generic.base import TemplateView

urlpatterns = [
    # path('admin/', admin.site.urls),
    path('',TemplateView.as_view(template_name="index.html")),
    path('',include('backend.urls')),
]

test_demo\backend\urls.py

from django.urls import path
from . import views

urlpatterns = [
    path('DataTest/',views.DataTest.as_view()),
    path('Search/',views.Search.as_view()),
]

test_demo\backend\views.py

from django.shortcuts import render
from rest_framework.views import APIView
from rest_framework.response import Response

# Create your views here.

class DataTest(APIView):
    def get(self,request,*args,**kwargs):
        print('請求後臺數據成功!')
        return Response(['後臺列表數據1','後臺列表數據2'])

class Search(APIView):
    def get(self,request):
        kw = request.GET.get('0', None)
        print(request.GET.get('0', None))
        if kw != None:
            return Response("您搜索的數據爲:" + kw)
        else:
            return Response("沒有搜索到任何數據")

到這裏我們的後端差不多完成了,只是我們現在寫的接口比較簡單,我只是爲了先能夠保證前後端能夠通信。
接下來我們把前端部分處理一下。

index.html

<body>
    <div id="app"></div>
    <!-- built files will be auto injected -->
  </body>

App.vue

<template>
  <div id="app">
    <nav class="top-menu">
      <div>
        <ul>
          <li v-for="item in menuList">
            <router-link :to="item.url">{{ item.name }}</router-link> <!-- 導航欄 -->
          </li>
        </ul>
      </div>
    </nav>
    <hr>
    <div>
      <router-view></router-view> <!-- 其他路由視圖(Home、Hello、DataTest) -->
    </div>
  </div>
</template>

<script>
export default {
  name: 'App',
  data:function () {
      return {
          menuList:[
              {name:'Home',url:'/home'}, // <!-- 導航欄對應的路徑 -->
              {name:'Hello',url:'/hello'},
              {name:'DataTest',url:'/data'}
          ] 
      }
  }
}
</script>

<style>
#app {
  font-family: 'Avenir', Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #42b983;
  margin-top: 60px;
}
.top-menu ul, .top-menu li {
  text-align: center;
  margin: 0 auto;
  list-style: none;
}
.top-menu {
  overflow: hidden;
  color: lightyellow;
}
.top-menu li {
  display: flex;
  float: right;
  width: 100px;
}
  body{
    background-image: url("assets/img/event-1.jpg");
  }
/*<!-- 導入外部css -->*/
  @import "assets/css/app.css";
  @import "assets/css/custom.css"; 
</style>

首頁效果圖
在這裏插入圖片描述
效果不是很好,如果你們前端技能很好可以自己再美化一點,哈哈哈哈哈哈哈。。。
接下來就是處理路由了

test_demo\firstvue\src\router\index.js

import VueRouter from 'vue-router';              // 導入路由模塊
import Home from './components/Home.vue';        // 導入Home組件
import Hello from './components/HelloWorld.vue';
import DataTest from "./components/DataTest";

export default new VueRouter({                  // 定義路由規則對象
  routes: [
    {path: '/home', component: Home},
    {path: '/hello', component: Hello},
    {path:'/data',component:DataTest}
  ]
})

Home.vue和Hello.vue視圖我就弄簡單一點,說明點擊後去到這個視圖就OK了

<template>
 <div class="home">
   <h3>{{msg}}</h3>
 </div>
</template>

<script>
    export default {
        name:'Home',
        data(){
            return {
                msg:'這裏是Home視圖'
            }
        }
    }
</script>

<style scoped>
h3 {
  background-color: chocolate;
}
</style>
<template>
  <div class="hello">
    <h1>{{ msg }}</h1>
    <h2>Essential Links</h2>

  </div>
</template>

<script>
export default {
  name: 'HelloWorld',
  data () {
    return {
      msg: '這裏是HelloWorld視圖'
    }
  }
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
h1, h2 {
  font-weight: normal;
  background-color: crimson;
}
ul {
  list-style-type: none;
  padding: 0;
}
li {
  display: inline-block;
  margin: 0 10px;
}
a {
  color: #42b983;
}
</style>

最主要還是在我們的DataTest.vue

<template>
  <div class="content mt-7 pt-5">
    <h1>This is DataTest</h1>
    {{d2}}
    <p v-for="d in d1">
      {{d}}
    </p>
    <button @click="init">點擊獲取數據</button>
    <div style="margin-top: 50px">
      <input id="search" name="search" ref="keywords">
      <button @click="search">搜索</button>
      <p style="color: black;margin-top: 10px">{{d3}}</p>
  </div>
  </div>

</template>

<script src="../assets/js/jquery-3.2.1.min.js"></script> <!--引入外部js-->
<script>
    export default {
        name: "DataTest",
        data:function(){
            return {
                d1:['默認列表數據1','默認列表數據2'],
                d2:'默認字符串',
                d3:'數據展示',
            }
        },
        methods:{
            init:function () {
                let _this = this;
                this.$http.request({
                    url:_this.$url+'DataTest/',
                    method:"get",
                }).then(function (response) {
                    console.log(response);
                    _this.d1 = response.data
                }).catch(function (response) {
                    console.log(response)
                })
            },
            search:function () {
                let _this = this;
                let val = _this.$refs.keywords.value;
                console.log(_this.$refs.keywords.value);
                this.$http.request({
                    url:_this.$url+'Search/',
                    method:"get",
                    params:val
                }).then(function (response) {
                    console.log(response);
                    _this.d3 = response.data
                }).catch(function (response) {
                    console.log(response)
                })
            }
        }
    }
</script>

<style scoped>
.content {
  color: aliceblue;
}
  @import "../assets/css/app.css"; /*引入外部css*/
  @import "../assets/css/custom.css";
</style>

我們的前段啓動命令如下:

npm install 安裝依賴
npm run dev 啓動web服務器,通過localhost:8080就可以訪問了

如果前段要與後端同步,則要將vue嵌入到django中:

npm run build
構建後,如果前端與後端有數據交換,賊需要前後端服務器都要開啓,
python manage.py runserver

點擊Home後的效果
在這裏插入圖片描述
點擊Hello後的效果
在這裏插入圖片描述
點擊DataTest效果:
在這裏插入圖片描述
我們嘗試點擊獲取數據,效果如下:
在這裏插入圖片描述
點擊搜索,效果如下:
在這裏插入圖片描述
在這裏插入圖片描述
這裏的結果跟我們預想是一樣的,所以一個django與vue的結合小測試就成功了,快去試驗一下吧!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章