服务器之家:专注于VPS、云服务器配置技术及软件下载分享
分类导航

node.js|vue.js|jquery|angularjs|React|json|js教程|

服务器之家 - 编程语言 - JavaScript - vue.js - 用 Vue 和 Django 快速搭建前后端分离项目

用 Vue 和 Django 快速搭建前后端分离项目

2022-09-01 17:05Python七号somenzz vue.js

Web 开发中前后端分离已经是常规性做法,但是不少初学者不太熟悉如何前后端分离,搭建 Demo 的时候遇到的问题也比较多,今天就来分享一下如何用 Vue 和 Django 快速搭建前后端分离项目。

Web 开发中前后端分离已经是常规性做法,但是不少初学者不太熟悉如何前后端分离,搭建 Demo 的时候遇到的问题也比较多,今天就来分享一下如何用 Vue 和 Django 快速搭建前后端分离项目。

先搭建前端

这里使用 Vue3,可以参考官方文档[1]。

在终端或者命令窗口执行:

npm init vue@latest

这将后自动安装 Vue 的最新版本,并初始化一个 Vue 项目,填写一个项目名称,其它都直接回车按默认值处理即可:

用 Vue 和 Django 快速搭建前后端分离项目

然后执行这些,就会看到前端项目启动了:

cd front_end
npm install
npm run dev

安装依赖

现在的前端项目,只会显示一个静态的网页,我们需要给它加点料,比如搞个表单,让它发起 get 或 post 请求,这样我们需要安装下面的依赖,在 front_end 目录下执行:

npm i element-plus -S
npm i axios -S
npm i mockjs -S

如果你用的是 Vue2,请安装 element-ui。

其中:

element-plus/element-ui 是 vue 的一个 ui 库,引入它主要为了使用一些好看的按钮,表单,文本框等,可以替换你喜欢的 ui 库,也可以不用。

axios 类似于 AJAX 的功能,主要为了访问后端 api 来获取数据。

mockjs 主要用于模拟后端的 api 接口返回数据。当前端工程师需要独立于后端并行开发时,后端接口还没有开发完成,那么前端怎么获取数据?这时可以考虑前端自己模拟假数据,mockjs 可用来生成随机数据,拦截 Ajax 请求。

导入依赖

现在,让我们修改 main.js ,全局引入 element,并使用 mockjs 模拟接口数据

import { createApp } from 'vue' import App from './App.vue' import ElementPlus from 'element-plus' import 'element-plus/dist/index.css' import './assets/main.css' import './mock' const app = createApp(App) app.use(ElementPlus) app.mount('#app')

这里,有个 mock.js,我们还没有编写,等会写。

编写一个 Demo 页面

在 front_end/src/components/ 下,编写一个 TestApi.vue 文件,内容如下:

<template> <el-form :inline="true" :model="formInline" size="small"> <el-form-item label="用户信息"> <el-input
        class="input" v-model="formInline.username" placeholder="用户名" >el-input> <el-input
        class="input" v-model="formInline.email" placeholder="email" >el-input> el-form-item> <el-form-item> <el-button type="primary" @click="onSubmitGet">get 查询所有el-button> <el-button type="primary" @click="onSubmitPost">post 提交el-button> el-form-item> <el-input
      type="textarea" :rows="6" placeholder="此处返回结果" v-model="results" class="textarea" > el-input> el-form> template> <script> import axios from "axios"; export default { data() { return { formInline: { username: "", email: "", }, results: "", }; }, methods: { onSubmitGet() { console.log("submit! get"); axios.get("api/users/") .then((res) => { this.results = JSON.stringify(res.data); console.log(res.data); //在console中看到数据 }) .catch((res) => { alert("wrong"); }); }, onSubmitPost() { console.log("submit! post"); axios.post("api/users/", this.formInline) .then((res) => { console.log(res.data); //在console中看到数据 }) .catch((res) => { alert("wrong"); }); }, }, }; script> <style scoped> .input { width: 200px; } button { width: 100px; } .textarea { width: 900px; } style>

上面的页面有一个表单,可以发起 get 或 post 请求。

这个组件写完了,需要把它展示到页面上,修改 App.vue 把所有 TheWelcome 替换成 TestApi 就可以了。

现在可以编写 mock.js 了,在 front_end 目录下,新建 mock.js 文件,写入以下内容:

//引入mockjs
import Mock from 'mockjs' // 获取 mock.Random 对象
const Random = Mock.Random; //使用mockjs模拟数据
Mock.mock('api/users/', (req, res) => { //当post或get请求到/api/users/路由时Mock会拦截请求并返回上面的数据
    var list = [{ "url": "http://127.0.0.1:8000/users/3.json", "username": "aaaaaa", "email": "", "groups": [] }, { "url": "http://127.0.0.1:8000/users/2.json", "username": "somenzz", "email": "", "groups": [] }, { "url": "http://127.0.0.1:8000/users/1.json", "username": "admin", "email": "admin@example.com", "groups": [] }] return list })

现在,再运行一下 npm run dev,浏览器打开 “http://127.0.0.1:5173/”,点击 get 按钮,会发现 mock 已经生效。

用 Vue 和 Django 快速搭建前后端分离项目

前端 demo 已经差不多了。

接下来让我们看看后端工程师的任务。

再搭建后端

这里以 DRF(Django REST Framework) 为例。如果对 DRF 还是第一次接触,建议先按官方的教程[2]走一遍。

执行以下命令创建一个后端 Demo:

django-admin startproject rear_end
cd rear_end
django-admin startapp restapi
#这一步会创建管理员用户,请记录设置的密码
python manage.py createsuperuser --email admin@example.com --username admin

接下来在 settings.py 文件中增加 'rest_framework' 到 INSTALLED_APPS 列表即可

接下来执行以下命令启动 django 后端服务。

python manage.py runserver

我们在浏览器中输入 http://127.0.0.1:8000/admin 然后输入管理员用户名和密码,再新增 3 个用户,可以随便填写,目的是为了多几条测试数据。

接下来访问 http://127.0.0.1:8000/user.json 可以看到返回如下 json 格式的数据。

用 Vue 和 Django 快速搭建前后端分离项目

后端开发工作至此告一段落。

前后端联调测试

开发环境下,vue 会占用一个端口,这里是 localhost:5173,而 djangorestframework 也会占用一个端口,比如 localhost:8000,那么 localhost:5137 需要获取 localhost:8000 的数据进行联调,因此我们将前端 demo 中 RestApi.vue 中请求的接口由 api/users 改为 http://127.0.0.1:8000/users.json,实际开发中通过配置文件来解决这个替换的问题。

实际执行的过程中,get 请求报错的结果如下:

Access to XMLHttpRequest at 'http://127.0.0.1:8000/users.json' from origin 'http://localhost:5137' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

这里翻译成中文就是,跨域资源共享(CORS)策略阻止了从 localhost:5137 到 127.0.0.1:8000 的访问。那么什么是跨域资源共享 ,这里得解释下:

跨域资源共享的目的是共享,它允许浏览器向跨源服务器,发出 XMLHttpRequest 请求,从而克服了 AJAX 只能同源使用的限制。显然,localhost:5137 到 localhost:8000 是不同源的,因此这里使用了跨域资源共享策略。但 CORS 需要浏览器和服务器同时支持。目前,所有浏览器都支持该功能,IE 浏览器不能低于 IE10。

整个 CORS 通信过程,都是浏览器自动完成,不需要用户参与。对于开发者来说,CORS 通信与同源的 AJAX 通信没有差别,代码完全一样。浏览器一旦发现 AJAX 请求跨源,就会自动添加一些附加的头信息,有时还会多出一次附加的请求,但用户不会有感觉。

因此,实现 CORS 通信的关键是服务器。只要服务器实现了 CORS 接口,就可以跨源通信。那么解决这个方法有两种:

第一种:设置服务器端,让它允许 localhost:5137 的跨域访问,上线后再改回来,为什么要改回来呢,因为要避免跨域攻击,详见知乎https://www.zhihu.com/question/26379635[3]。

第二种:将 127.0.0.1:8000 返回的 json 数据复制到 mock 的方式来联调。

看来第二种比较方便,前提是你需要学习如何使用 mock 来模拟后端 api。

为了在开发环境联调,我们将第一种方法进行到底,现在修改 django 的配置文件 settings.py 让它允许跨域。

1、安装 django-cors-headers

pip install django-cors-headers

2、修改 settings.py

INSTALLED_APPS = [ ...... 'corsheaders', ...... ] MIDDLEWARE = [ ...... 'corsheaders.middleware.CorsMiddleware', 'django.middleware.common.CommonMiddleware', ...... ] CORS_ORIGIN_ALLOW_ALL = True CORS_ALLOW_CREDENTIALS = True

此时,执行 get 请求顺利完成。

这里,我们填写用户名和邮箱,提交 post 请求后,users 表会新增一条记录,通过 get 请求也可以查询出来,大家可以动手试一试。

实际开发中,我们在请求后端接口时的 url 一般不会填写 ip 地址和端口,而是 'api/xxx' 这种形式,这里是为了展示如何在开发环境进行前后端联调而写成此种形式。

上线部署

先执行 npm run build 来打包,默认配置上,将生成 dist 目录,并在 dist 目录下产生 index.html 文件,及静态资源 js,css,fonts,它们都在 dist 目录下。

这个 dist 目录就是需要我们上线部署的资源。

我到网上搜索了一下, 有两种主流方式,一种是直接将 dist 目录位置配置在 nginx 上,然后使用 nginx 反向代理 UWSGI 或 gunicorn,通常使用 socket 协议。

另外一种是将 dist 目录的资源由 django 驱动,这样就不涉及跨域的问题,但需要在打包时稍做调整。在 front_end 目录下新建 vue.config.js 文件,并添加以下内容:

module.exports = { // 选项...
  assetsDir : 'static' }

再次执行 npm run build 我们会发现 js,css,fonts 都放在 static 目录下了,这样做的原因是:django 模板视图指定的 html 文件不能与静态资源放在同一路径下,至少有一个相对目录才可以。换句话说,django 配置文件中 STATIC_URL 默认为 '/static/' ,不允许设置为空,就是说,127.0.0.1:8000/static/js/xxx.js 才能正确的访问静态资源,但默认的 vue 默认配置生成的静态资源和 index.html 是同级的,因此需要稍微调整下才可以。

接下来修改下 django 的配置文件:

1、可以注释掉所有关于跨域的代码。参考前面的步骤 2、增加以下配置,让 django 在 debug 模式下能找到静态资源

STATICFILES_DIRS = [os.path.join(BASE_DIR, "dist/static")] TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [os.path.join(BASE_DIR,'dist')], 'APP_DIRS': True, 'OPTIONS': { 'context_processors': [ 'django.template.context_processors.debug', 'django.template.context_processors.request', 'django.contrib.auth.context_processors.auth', 'django.contrib.messages.context_processors.messages', ], }, }, ] 

修改 setting.py 同目录的 urls.py 加入模板视图,指定 index.html

urlpatterns = [ path('admin/', admin.site.urls), path('', TemplateView.as_view(template_name="index.html"), name='index'), path('', include(router.urls)), path('api-auth/', include('rest_framework.urls', namespace='rest_framework')) ]

执行 python manage.py runserver 后打开浏览器,执行 get 请求,可以看到如下结果,此时前后端已经同源。

再接下来的配置基本和第一种方案一样了,设置 django 收集静态资源的路径 STATIC_ROOT,执行 python manage.py collectstatic ,然后参考下面 uwsgi 的配置进行生产环境部署,这种方法不需要后端允许跨源,比较安全。

生产环境上线,你需要了解一下 nginx 及 uwsgi。

nginx 可以指定首页 index.html,静态资源,端口转发,路由转发,负载均衡等等,网上有详细的配置说明,不再列举。uwsgi 也可以指定静态资源,主要用来驱动 django。这里贴一份我使用过的配置:

[uwsgi] socket = :80 master = true chdir = /home/aaron/web/django-mysite
wsgi-file = blogproject/wsgi.py processes = 4 threads = 10 virtualenv = /home/aaron/pyenv
static-map = /static=/home/aaron/web/django-mysite/static
static-map = /media=/home/aaron/web/django-mysite/media
mime-file = /home/aaron/web/django-mysite/mime.types disable-logging
logto = /home/aaron/web/django-mysite/uwsgi.log #使进程在后台运行,并将日志打到指定的日志文件或者udp服务器
daemonize = /home/aaron/web/django-mysite/uwsgi.log

参考资料

[1]官方文档: https://vuejs.org/guide/quick-start.html#with-build-tools

[2]官方的教程: https://www.django-rest-framework.org/tutorial/quickstart/

[3]https://www.zhihu.com/question/26379635: https://www.zhihu.com/question/26379635

原文地址:https://mp.weixin.qq.com/s/LjqtEyC9nhTr8ivdrnNSDg

延伸 · 阅读

精彩推荐
  • vue.jsVue SPA 首屏优化方案

    Vue SPA 首屏优化方案

    这篇文章主要介绍了Vue SPA 首屏优化方案的的相关资料,帮助大家更好的理解和学习使用vue,感兴趣的朋友可以了解下...

    小豪看世界7132022-01-24
  • vue.jsVue 虚拟列表的实战示例

    Vue 虚拟列表的实战示例

    这篇文章主要介绍了Vue 虚拟列表的实现示例,帮助大家更好的理解和学习使用vue,感兴趣的朋友可以了解下...

    掘金安东尼6462022-02-19
  • vue.jsvue实现可移动的悬浮按钮

    vue实现可移动的悬浮按钮

    这篇文章主要为大家详细介绍了vue实现可移动的悬浮按钮,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    丢失的蓝胖子7482022-02-10
  • vue.jsVue ​v-model相关知识总结

    Vue ​v-model相关知识总结

    这篇文章主要介绍了Vue ​v-model相关知识总结,帮助大家更好的理解和学习使用vue框架,感兴趣的朋友可以了解下...

    码农译站4242022-01-10
  • vue.jsvue实现验证用户名是否可用

    vue实现验证用户名是否可用

    这篇文章主要为大家详细介绍了vue实现验证用户名是否可用,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    河软小宝9262022-01-05
  • vue.jsSpringBoot+Vue 前后端合并部署的配置方法

    SpringBoot+Vue 前后端合并部署的配置方法

    这篇文章主要介绍了SpringBoot+Vue 前后端合并部署的配置方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参...

    可乐要加冰11752021-12-23
  • vue.js聊聊vue 中的v-on参数问题

    聊聊vue 中的v-on参数问题

    这篇文章主要介绍了聊聊vue 中的v-on参数问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...

    Firoly8012022-01-11
  • vue.jsElement-ui upload上传文件限制的解决方法

    Element-ui upload上传文件限制的解决方法

    这篇文章主要介绍了Element-ui upload上传文件限制的解决方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的...

    MrQiu8422022-01-06