在本教程中,我们将解释如何将vue.js单页应用程序与Flask后端连接起来。
一般来说,如果只是想通过Flask模板使用vue.js库,是没有问题的。但实际上是一个很明显的问题,就是Jinja(模板引擎)也像Vue.js一样使用双大括号进行渲染,但只是一个相当不错的解决方案。
我想要一个不同的例子。如果我需要构建一个单页应用(应用由单页组成,HTML5中vue-router的History-mode等有用的功能),使用vue.js,Flask提供Web服务?简单来说,应该是这样的,如下:
Flask服务于index.html,index.html包含我的vue.jsapp。
在前端开发中,我使用了Webpack,它提供了所有很酷的功能。
Flask有一个API,我可以从我的SPA访问它。
我可以访问API端,甚至在我运行Node.js进行前端开发的时候。
听起来很有趣吧?让我们这样做。
完整的源代码,你可以在这里找到:https://github.com/oleg-agapov/flask-vue-spa
客户
我会用Vue CLI生成基本的vue.jsapp,如果你还没有安装,请运行:
$ npm install -g vue-cli客户端和后端代码将被拆分到不同的文件夹中。初始化前端部分运行跟踪:
$ mkdir flashvue $ CD flashvue $ vueinit web pack前端通过安装向导。我的设置是:
Vue只在运行时构建。
安装Vue路由器。
使用ESLint检查代码。
选择一个ESLint标准预设。
单元测试不要尝试Karma摩卡。
在不使用夜间观察的情况下建立端到端测试。
好吧,那就来吧:
$ cdfrontend $ npminstall #安装$ npmrundev后,就可以开始安装vue.js应用程序了。让我们从添加一些页面开始。
将home.vue和about.vue添加到front/src/components文件夹中。它们很简单,就像这样:
//home . vuetemplatedivome页面/p/div/templateand
//about . vuetemplatedivpabout/p/div/template我们将使用它们来正确识别我们当前的位置(根据地址栏)。现在我们需要更改前端/src/路由器/index.js文件来使用我们的新组件:
从“vue”导入Vue从“vue-router”导入Router const routerOptions=[{ path : '/',component: 'Home' },{ path : '/' About ',component : ' About ' }]const routes=routerOptions . map(route={ return }.route,component :()=import(`@/components/$ { route.component } . vue `)})vue . use(Router)export default new Router({ routes,Mode: 'history'})如果尝试输入localhost:8080和localhost 33608080/about,应该会看到相应的页面。
我们几乎准备好构建一个项目,并可以创建一个静态资源包。在此之前,让我们为它们重新定义输出目录。在front/config/index . js中查找下一个设置:
索引:路径。resolve (_ _ dirname ',/dist/indexhtml '),资产root:路径。resolve (_ _ dirname ',/dist '),将它们更改为
index : path . resolve(_ _ dirname,'././dist/index.html '),assets root : path . resolve(_ _ dirname ',/./dist '),因此/dist文件夹的HTML、CSS和JS将位于同一级别的目录中。现在,您可以运行$ npm运行构建来创建包。
后端
对于Flask服务器,我将使用Python版本。在/flashvue中创建新的子文件夹,以存储后端代码并初始化虚拟环境:
$ mkdir后端$ CD后端$ virtualenv-p python3venv在虚拟环境(MacOS)中运行:
$ source venv/bin/activate需要在Windows中激活此文档。
在虚拟环境中安装:
(venv) pip安装Flask现在让我们为闪存服务器编写代码。创建根文件run.py:
光盘.将下一个代码添加到该文件中:
从flask导入Flask,render _ template app=Flask(_ name _ _,static_folder='。/dist/static ',Template _ folder='。/dist ')@ app . route('/')def index(): return render _ template(' index . html ')与Flask的* *“hello world”* *代码略有不同。主要区别是我们指定了静态文件和模板在文件夹/dist中的存储位置,以便与我们的前端文件夹区分开来。在根文件夹中运行Flask服务器:
(venv)flare _ app=run . py flask _ debug=1 flare run这将在本地主机:localhost:5000上启动flare _ app服务器的启动文件,flare _ debug=1将以调试模式运行。如果一切正常,你会看到熟悉的主页,你已经完成了Vue的设置。
同时,如果您试图进入/关于页面,您将面临一个错误。Flask抛出一个错误,表示找不到请求的网址。实际上,因为我们使用HTML5的历史模式,所以我们需要在Vue路由器中配置网络服务器的重定向,并将所有路径指向index.html。用Flask很容易做到。将现有路线修改为:
@ app.route ('/',默认值={ ' path ' : ' ' })@ app . route('/path : path ')def catch _ all(path): return render _ template(' index . html ')现在输入URL localhost :5000。
增加404页
因为我们有一个全包路径,我们的Web服务器很难赶上404错误,Flask将所有请求指向index.html(甚至不存在的页面)。因此,我们需要处理vue.js应用中的未知路径。当然,所有的工作都可以在我们的路由文件中完成。
在front/src/router/index . js中添加以下行:
const routerOptions=[{ path : '/',component: 'Home' },{ path : '/' About ',component: 'About' },{ path: '*,Component: 'NotFound' }]这里的路径' * '是通配符,Vue-router知道除了上面定义的路径以外的所有其他路径。现在我们需要在**/components**目录中创建更多的NotFound.vue文件。很容易尝试:
//not found . vuetemplatediv p 404-not found/p/div/template,现在运行的前端服务器是npm再次运行dev,试图输入一些无意义的地址,比如localhost :8080/gljhewrogh。您应该会看到我们的“未找到”消息。
添加应用编程接口端
我们的vue.js/flask教程的最后一个例子是服务器端应用编程接口创建和调度客户端。我们将创建一个简单的Api,它将返回一个从1到100的随机数。
打开run.py并添加:
从flask导入Flask,render_template,jsonifyfrom随机导入* app=Flask(_ name _ _,static_folder='。/dist/static ',template_folder='。/dist ')@ app . route('/API/random ')def random _ number(): response={ ' random number ' : randint(1,100)} return jsonify(response)@ app . route('/',默认值={ ' path ' : ' ' })@ app . route('/path : path ')def catch _ all(path): return render _ template(' index。然后我添加了一个新的路由/api/random来返回JSON,如下所示:
{'randomNumber': 36}您可以通过在本地浏览来测试此路径:localhost:5000/api/random。
此时,服务器端的工作已经完成。是时候在客户端展示了。让我们更改home.vue组件显示的随机数:
templatedivome page/ppRandom number from backend : { { random number } }/pbutton @ click=' getRandom ' new random number/button/div/templatescript export default { data(){ return { random number : 0 0 } },methods : { getRandom nt(min,max){ min=math . ceil(min)max=math . floor(max)return math . floor(math . random()*(max-min-1))min },Getrandom () {this。随机数=这个。getrandom int (1,100)}},created () {this。getrandom ()}}/script现阶段,我们只模仿客户端的随机数生成过程。这个组件是这样工作的:
初始化时,变量randomNumber等于0。在方法部分,我们使用getRandomInt(min,max)函数返回指定范围内的随机数。getrandom函数将生成随机数,并将它们分配给随机数组件方法,该方法将在创建随机数后被调用来初始化随机数。在按钮的点击事件中,我们将使用getrandom方法获取新的随机数。现在在主页上,你应该看到前端显示了我们生成的随机数。让我们把它连接到后端。
为此,我将使用axios库。它允许我们用响应HTTP请求,用Json返回JavaScript Promise。让我们安装它:
(venv)光盘前端(venv) NPM安装-保存axios,打开home.vue并在脚本中添加一些更改:
从' axios ' methods : { getRandom(){//this . random number=this . getRandom nt(1,100)this . random number=this .getrandomfrom后端()}、getrandomfrom后端(){ const path=` http://localhost :5000/API/random ` axios . get(路径)导入axios。然后(response={ this . random number=response . data . random number })。catch(error={ console . log(error)})} }在顶部,我们需要参考Axios库。然后一个新的方法getrandomfrombender将使用Axios调用API并异步检索结果。最后,getrandom方法现在应该使用getrandom from后端函数来获取一个随机值。
保存文件,转到浏览器,运行开发服务器,再次刷新localhost:8080。您应该看到控制台错误没有随机值。不过不用担心,一切正常。我们得到了CORS错误,这意味着Flask服务器API将默认关闭其他Web服务器(在我们的例子中,vue.js App是一个运行在Node.js服务器上的应用程序)。如果您运行NPM构建项目,您将看到该应用程序在localhost:5000(如Flask服务器)中工作。但是,每次对客户端应用程序进行一些更改时,创建一个包并不太方便。
让我们使用CORS插件打包的Flask,这将使我们能够创建一个API访问规则。这个插件叫做FlaskCORS,让我们安装它:
(venv) pip install-u flash-CORS您可以阅读文档,以更好地解释您希望服务器如何使用CORS。我将使用特定的方法,将* * {“origins”:“*”} * *应用到所有/api/*路由中(这样每个人都可以使用我的api端)。添加到run.py:
从FLASK _ CORS导入corsabp=FLASK(_ _ name _ _,static _ folder='。/dist/static ',template _ folder='。/dist') CORS=CORS (app,resources={ r '/API/* ' : { ' origins)
更新:
事实上,如果您想通过Flask提供静态文件,则不需要CORS。感谢卡森吉的跟进。
想法是这样的。如果应用程序处于调试模式,它将只代理我们的前端服务器。否则(在生产中),它只提供静态文件。我们是这样做的:
import requests@app.route('/',默认值={ ' path ' : ' ' })@ app . route('/path : path ')def catch _ all(path): if app . debug : return requests . get(' http://localhost :8080/{ }。格式(路径))。文本返回render _ template ('index.html ')优雅神奇:sparkles:
现在您有了一个完整的**(全栈应用程序,它是用您最喜欢的Vue.js和Flask**技术构建的。
附言
最后,我想就如何改进这个解决方案说几句话。
如果您希望您的应用编程接口访问外部服务器,请首先使用CORS。否则,您只需要使用代理服务器和前端开发技能。
另一个改进是避免客户端硬编码API路由。也许你需要考虑一些API端点的字典。因此,当您更改API路由时,您只需要刷新一个字典。前端仍然有一个有效的端点。
通常在开发过程中,你至少有两个终端窗口:一个是Flask,一个是vue.js在生产中,你可以摆脱vue,单独运行Node.js服务器。
源代码:https://github.com/oleg-agapov/flask-vue-spa
以上就是本文的全部内容。希望对大家的学习有帮助,支持我们。