前言
最近公司要做一个系统,需要前后端分离,后端使用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的结合小测试就成功了,快去试验一下吧!