Vue + Django — 使用两种前端框架的优势

Django和Vue都具有独特的前端优势。Django的上下文驱动模板视图提供了从后端模型内容直接快速开发页面的功能。Vue的现代reactive组件为在丰富的Javascript生态系统中构建复杂的UI提供了强大的工具。

(此处已添加圈子卡片,请到今日头条客户端查看)

然而,将Django和Vue同时使用的典型解决方案削弱了单独使用其中一种的优势。例如,一种常见的方法是使用Django Rest框架作为后端,然后用Vue编写整个前端,这样就很难在方便的地方使用Django模板。第二种方法是在Django模板中使用Vue,通过使用浏览器<script>标记将Vue代码引入,但是这样做就丧失了使用Vue单个文件组件的能力。

Vue + Django — 使用两种前端框架的优势

最近我启动了一个项目,我想同时使用Django模板和Vue,而不相互影响。我的站点的大多数页面都是相对静态的后端数据列表,交互性有限,这正是Django仅用几行代码就能做到的。但我还有很少的页面包含了更复杂的数据驱动交互区域,而这是Vue的强项。我能不能找到一种方法,在使用Vue丰富页面的部分内容的同时,在更简单的页面上使用Django模板,所有这些都在一个易于管理的配置中呢?

我可以同时拥有两个框架的优势吗?

那是当然!如果不是这样,这篇文章就显得非常无关紧要了。

Django Webpack加载器和Vue多页面应用程序

这个解决方案的关键部分是django -webpack-loader Django应用程序和Vue支持多页面应用程序的能力。通过结合这些工具,我们可以构建一个标准的模板驱动的Django应用程序,该应用程序在Django视图中包含一个或多个独立的webpack包。每个包都是一个单独的Vue“页面”,该页面可以使用所有标准的Vue/Javascript/Webpack工具来构建。

调整Django项目来使用Vue

在本文余下的部分中,我将演示如何修改一个基本的模板驱动的Django应用程序,以使用Vue的单个文件组件。我省略了构建一个简单Django站点的步骤,因为它已经有了很详细的文档,但是如果你想要一个更简单的起点,你可以从example_start标记处访问并使用本文的示例仓库。

出于本文的目的,我假设你有两个工作模板,你希望将单独的Vue组件添加到其中。

在我的示例仓库中,这两个工作模板是templates/vue_app_01.html和templates/vue_app_02.html。

Vue + Django — 使用两种前端框架的优势

添加一个简单的Vue项目

首先,我们将在Django项目的子目录中嵌入整个简单的Vue项目。首先,确保你安装了Vue CLI。

Vue + Django — 使用两种前端框架的优势

然后,我们将使用CLI来构建通常要有的 Vue 开始项目,并将其放在vue_frontend目录中

Vue + Django — 使用两种前端框架的优势

你只需要接受CLI提供的所有缺省值即可。当该项目成功创建时,你会看到CLI的报告信息。我们可以启动它来验证我们的开始项目是否正常工作:

Vue + Django — 使用两种前端框架的优势

将浏览器指向启动服务命令报告给你的URL(可能是http://localhost:8080),你应该就会看到Vue示例应用程序。

Vue + Django — 使用两种前端框架的优势

关于如何配置/自定义这个项目的指南或教程,请查看vue-cli文档

将Vue单页应用程序转换为多页应用程序

这个开始项目只有index.js一个入口点。我们将把这个项目转换为使用多个“页面”作为入口点的项目。

首先,我们需要一个助手包webpack-bundle-tracker来帮助我们跟踪由这些多个页面创建的bundle包。你可以从vue_frontend目录运行以下命令,将该助手包添加到项目中。

Vue + Django — 使用两种前端框架的优势

接下来,我们将重新配置这个Vue项目。创建带有以下内容的vue_fontend / vue.config.js文件:

Vue + Django — 使用两种前端框架的优势
Vue + Django — 使用两种前端框架的优势

我们来研究一下这个配置。

在前面,我们声明了一个包含页面vue_app_01和vue_app_02的列表,它们将成为我们bundle包的名称,并且我们还为为每个页面定义入口点。注意main.js附带了我们的开始应用程序,但是我们还没有构建newhampshir.js。我们稍后将构建它。

publicPath部分定义了Django将如何定位我们的bundle包。我们有两种变体可以使用,一种用于生产,另一种用于非生产。在生产中,我们将publicPath设置为空,通过此操作来向django -webpack-loader发出信号,使其退回到Django的标准静态查找器行为。但是,在非生产模式下,我们将覆盖此命令并将其指向我们自己的webpack开发服务器。

outputDir定义了用于生产的Javascript/CSS将放在什么地方。这很可能是你的Django应用程序的一个静态文件位置。

接下来,我们使用splitChunks插件优化我们的构建,对它进行配置使其能够将任何供应商的javascript提取到一个共享bundle中。这样我们就能够保持我们组件的javascript文件很小,并允许浏览器在多个页面之间移动时可以缓存常用的javascript。

默认情况下,Vue会为我们的bundle构造相应的html文件,但是我们不需要这些文件,因为我们可以从Django模板中获取这些文件。通过从配置中删除适当的插件,我们可以阻止这些文件的生成。

BundleTracker插件将创建一个vue_frontend/webpack-stats.json文件, 用来描述此构建过程生成的bundle资源包。此文件最终将被django-webpack-loader用来标识和提供我们的bundle资源包。稍后我会详细介绍。

STATIC别名是Alejandro Riera Mainar首先描述(我认为)的一个巧妙的技巧。它允许我们在Vue组件中按照下边的形式来引用静态文件的路径:

Vue + Django — 使用两种前端框架的优势

最后,我们来配置一个用于非生产模式的开发服务器,并允许我们在前端开发期间热加载Vue组件。

现在已经配置了Vue,我们需要创建我们的组件。这些组件可以是任何Vue应用程序,但是对于本文,我将只修改starter项目。我们将starter项目的main.js和App. vue转换成另一个稍微不同的应用程序。

Vue + Django — 使用两种前端框架的优势

接下来,使用vim或你最喜欢的简洁的编辑器去更新src/newhampshir.js,使其指向我们新的App02组件,或者,如果你有sed工具,只需运行以下代码:

Vue + Django — 使用两种前端框架的优势

同样,对这个App02组件做一个简单的更改,这样我们就能够从浏览器中识别它。再次使用一个编辑器或简单地运行:

Vue + Django — 使用两种前端框架的优势

现在我们的Vue前端已经准备好了。我们可以通过执行yarn build命令来确认所有东西都已经正确地构建了。你应该会看到一些与下面类似的结果:

Vue + Django — 使用两种前端框架的优势

对Django进行配置使其使用webpack bundle资源包

现在我们的Vue应用程序正在正确地构建bundle资源包,我们只需要指导Django如何定位和解析这些包。django-webpack-loader项目为我们解决了这方面的大部分问题。在你的requirements.txt中加入以下行,将这个包添加到你的Django应用程序中:

Vue + Django — 使用两种前端框架的优势

然后安装新的依赖项:

Vue + Django — 使用两种前端框架的优势

在你的Django设置文件中(例如settings.py),将webpack_loader添加到INSTALLED_APPS列表中。

在相同设置文件的其他地方,添加以下行:

Vue + Django — 使用两种前端框架的优势

这个配置会将django-webpack-loader指向我们在Vue构建期间生成的stats文件。

到这里差不多就完成了。最后一步是修改模板,将我们新的Vue应用程序包括进来。选择一个你现有的Django模板文件(在我的例子中是vue_app_01.html),并添加以下内容:

Vue + Django — 使用两种前端框架的优势

这段代码为我们的应用程序预留了一个容器,然后将来自供应商的bundle包和我们的vue_app_01 bundle包所需要的所有Javascript和CSS包含进来。注意,你可以将任何现有的Django模板代码混合到这些新增代码中。

选择第二个模板并包含相同的内容,除了替换vue_app_02 bundle包。

运行这个应用程序

要在开发模式下运行我们的应用程序,我们需要同时提供Django的开发服务器和webpack开发服务器。从vue_frontend目录中运行:

Vue + Django — 使用两种前端框架的优势

并且,在Django根目录中的另一个终端中运行Django开发服务器,例如。

Vue + Django — 使用两种前端框架的优势

将浏览器指向你的Django应用程序(例如http://localhost:8000),查看你修改的两个页面。你应该能看到你的模板,但是现在每个模板都运行着一个单独的Vue组件。

Vue + Django — 使用两种前端框架的优势

检查浏览器的开发控制台,你可以看到Vue JS/CSS是由我们的webpack开发服务器提供的。再有,这两个组件共享着相同的chunk-vendor .js bundle包。此外,我们可以通过更改我们的组件之一来演示热重载是正确运行的。不需要重新加载,更新就会直接在浏览器中生效。

是时候进行部署的时候,或者当我们只是想要省略运行Vue 开发服务器时,我们就可以在生产模式中构建我们的Vue项目。如果 yarn serve进程正在运行,就取消它,并运行yarn build。优化后的bundle包将内置于我们的Django静态文件位置,并且 webpack-stats.json将会被更新来生效这个新配置。回到你的web浏览器,重新加载页面,你会看到Vue JS/CSS bundle包现在已经从标准静态文件位置来加载了。

结论

结合Django模板和Vue并不要求你在这两种模板的优点上做出妥协。使用本文描述的技术,你可以在项目中任何适当的时间和地点自由地利用它们。

补充说明

本例中使用的Vue组件非常简单,但是你可以随心所欲地将它们变得复杂,通过Vuex和Vuetify等技术、第三方node模块或其他webpack配置。只需修改你的Vue/Webpack配置,就像使用任何标准的Vue项目一样。

使用这项技术,你就不受限于每页只有一个Vue组件。如果你希望将多个组件挂载在单个页面上的单独容器中,只需使用一个单独的选择器来相应地挂载每个组件。

我不提倡任何特定的生产配置方法。你可能希望提交一个生产webpack-stats.json,为开发/生产环境维护两个单独的版本,或者将bundle包的构建和webpack-stats.json包含到你的交付进程中。

致谢

Rodrigo Smaniotto的那篇极好的文章——“使用Vue CLI 3和Webpack Loader将Django和VueJs集成在一起”——教会了我如何使用django-webpack-loader去集成一个Vue单页面应用程序。本文描述的大部分django-webpack-loader配置都是基于他的研究工作。

Rodrigo的文章和本文还使用了Alejandro Riera Mainar的“使用Django + webpack + Vue建立一个易于开发和部署的新项目(第1部分)”这篇文章中的内容。

注:我这有个学习Python基地,里面有很多学习资料,感兴趣的+Q群:895817687

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,544评论 6 501
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,430评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,764评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,193评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,216评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,182评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,063评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,917评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,329评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,543评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,722评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,425评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,019评论 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,671评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,825评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,729评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,614评论 2 353

推荐阅读更多精彩内容

  • 基于Vue的一些资料 内容 UI组件 开发框架 实用库 服务端 辅助工具 应用实例 Demo示例 element★...
    尝了又尝阅读 1,149评论 0 1
  • 前几日听到一句生猛与激励并存,可怕与尴尬同在,最无奈也无解的话:“90后,你的中年危机已经杀到”。这令我很受触动。...
    王钰峰阅读 4,381评论 1 22
  • UI组件 element- 饿了么出品的Vue2的web UI工具套件 Vux- 基于Vue和WeUI的组件库 m...
    小姜先森o0O阅读 9,476评论 0 72
  • UI组件 element- 饿了么出品的Vue2的web UI工具套件 Vux- 基于Vue和WeUI的组件库 m...
    柴东啊阅读 15,852评论 2 140
  • UI组件 element- 饿了么出品的Vue2的web UI工具套件 Vux- 基于Vue和WeUI的组件库 m...
    王喂马_阅读 6,454评论 1 77