在這個(gè)教程中,我們將講解如何將vue.js單頁應(yīng)用與Flask后端進(jìn)行連接。
建始ssl適用于網(wǎng)站、小程序/APP、API接口等需要進(jìn)行數(shù)據(jù)傳輸應(yīng)用場(chǎng)景,ssl證書未來市場(chǎng)廣闊!成為成都創(chuàng)新互聯(lián)的ssl證書銷售渠道,可以享受市場(chǎng)價(jià)格4-6折優(yōu)惠!如果有意向歡迎電話聯(lián)系或者加微信:028-86922220(備注:SSL證書合作)期待與您的合作!
一般來說,如果你只是想通過Flask模板使用vue.js庫也是沒有問題的。但是,實(shí)際上是一個(gè)很明顯的問題那就是,Jinja(模板引擎)也和Vue.js一樣采用雙大括號(hào)用于渲染,但只是一個(gè)還算過的去的解決方案。
我想要一個(gè)不同的例子。如果我需要建立一個(gè)單頁應(yīng)用程序(應(yīng)用程序使用單頁組成, vue-router在HTML5的History-mode以及其他更多好用的功能)用vue.js,由Flask提供Web服務(wù)?簡(jiǎn)單地說應(yīng)該這樣,如下所示:
Flask為 index.html服務(wù), index.html包含我的vue.js App。
在前端開發(fā)中我使用Webpack,它提供了所有很酷的功能。
Flask有API端,我可以從我的SPA訪問。
我可以訪問API端,甚至當(dāng)我為了前端開發(fā)而運(yùn)行Node.js的時(shí)候。
聽起來是不是很有趣?那讓我們這樣動(dòng)手做做吧。
完整的源代碼,你可以在這里找到:https://github.com/oleg-agapov/flask-vue-spa
客戶端
我將使用Vue CLI產(chǎn)生基本vue.js App。如果你還沒有安裝它,請(qǐng)運(yùn)行:
$ npm install -g vue-cli
客戶端和后端代碼將被拆分到不同的文件夾。初始化前端部分運(yùn)行跟蹤:
$ mkdir flaskvue $ cd flaskvue $ vue init webpack frontend
通過安裝向?qū)?。我的設(shè)置是:
Vue 只在運(yùn)行時(shí)構(gòu)建。
安裝Vue-router。
使用ESLint檢查代碼。
選擇一個(gè)ESLint 標(biāo)準(zhǔn)預(yù)設(shè) 。
不試用Karma + Mocha進(jìn)行單位測(cè)試。
不使用Nightwatch建立端到端的測(cè)試。
ok,接著來:
$ cd frontend $ npm install # after installation $ npm run dev
這就可以開始安裝 vue.js應(yīng)用程序。讓我們從添加一些頁面開始吧。
添加 home.vue和 about.vue到 frontend/src/components文件夾。它們非常簡(jiǎn)單,像這樣:
// Home.vue <template> <div> <p>Home page</p> </div> </template>
and
// About.vue <template> <div> <p>About</p> </div> </template>
我們將使用它們正確地識(shí)別我們當(dāng)前的位置(根據(jù)地址欄)?,F(xiàn)在我們需要改變 frontend/src/router/index.js文件以便使用我們的新組件:
import Vue from 'vue' import Router from 'vue-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:8080/about,你應(yīng)該看到相應(yīng)的頁面。
我們幾乎已經(jīng)準(zhǔn)備好構(gòu)建一個(gè)項(xiàng)目,并且能夠創(chuàng)建一個(gè)靜態(tài)資源文件包。在此之前,讓我們?yōu)樗鼈冎匦露x一下輸出目錄。在 frontend/config/index.js找到下一個(gè)設(shè)置:
index: path.resolve(__dirname, '../dist/index.html'), assetsRoot: path.resolve(__dirname, '../dist'),
把它們改為
index: path.resolve(__dirname, '../../dist/index.html'), assetsRoot: path.resolve(__dirname, '../../dist'),
所以/dist文件夾的HTML、CSS、JS會(huì)在同一級(jí)目錄/frontend ?,F(xiàn)在你可以運(yùn)行 $ npm run build創(chuàng)建一個(gè)包。
后端
對(duì)于Flask服務(wù)器,我將使用Python版本3.6。在 /flaskvue創(chuàng)建新的子文件夾存放后端代碼并初始化虛擬環(huán)境:
$ mkdir backend $ cd backend $ virtualenv -p python3 venv
為了使虛擬環(huán)境中運(yùn)行(MacOS):
$ source venv/bin/activate
在Windows中需要激活此文檔(http://pymote.readthedocs.io/en/latest/install/windows_virtualenv.html)。
在虛擬環(huán)境下安裝:
(venv) pip install Flask
現(xiàn)在讓我們?yōu)镕lask服務(wù)端編寫代碼。創(chuàng)建根目錄文件run.py:
(venv) cd .. (venv) touch run.py
向這個(gè)文件添加下一個(gè)代碼:
from flask import 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”**代碼略有不同。主要的區(qū)別是,我們指定存儲(chǔ)靜態(tài)文件和模板位置在文件夾 /dist,以便和我們的前端文件夾區(qū)別開。在根文件夾中運(yùn)行Flask服務(wù)端:
(venv) FLASK_APP=run.py FLASK_DEBUG=1 flask run
這將啟動(dòng)本地主機(jī)上的Web服務(wù)器: localhost:5000上的 FLASK_APP服務(wù)器端的啟動(dòng)文件, flask_debug = 1將運(yùn)行在調(diào)試模式。如果一切正確,你會(huì)看到熟悉的主頁,你已經(jīng)完成了對(duì)Vue的設(shè)置。
同時(shí),如果您嘗試輸入/about頁面,您將面臨一個(gè)錯(cuò)誤。Flask拋出一個(gè)錯(cuò)誤,說找不到請(qǐng)求的URL。事實(shí)上,因?yàn)槲覀兪褂昧薍TML5的History-Mode在Vue-router需要配置Web服務(wù)器的重定向,將所有路徑指向index.html。用Flask做起來很容易。將現(xiàn)有路由修改為以下:
@app.route('/', defaults={'path': ''}) @app.route('/<path:path>') def catch_all(path): return render_template("index.html")
現(xiàn)在輸入網(wǎng)址localhost:5000/about 將重新定向到index.html和vue-router將處理路由。
添加404頁
因?yàn)槲覀冇幸粋€(gè)包羅萬象的路徑,我們的Web服務(wù)器在現(xiàn)在已經(jīng)很難趕上404錯(cuò)誤,F(xiàn)lask將所有請(qǐng)求指向index.html(甚至不存在的頁面)。所以我們需要處理未知的路徑在vue.js應(yīng)用。當(dāng)然,所有的工作都可以在我們的路由文件中完成。
在frontend/src/router/index.js添加下一行:
const routerOptions = [ { path: '/', component: 'Home' }, { path: '/about', component: 'About' }, { path: '*', component: 'NotFound' } ]
這里的路徑'*'是一個(gè)通配符, Vue-router就知道除了我們上面定義的所有其他任何路徑?,F(xiàn)在我們需要更多的創(chuàng)造 NotFound.vue文件在**/components**目錄。試一下很簡(jiǎn)單:
// NotFound.vue <template> <div> <p>404 - Not Found</p> </div> </template>
現(xiàn)在運(yùn)行的前端服務(wù)器再次 npm run dev,嘗試進(jìn)入一些毫無意義的地址例如: localhost:8080/gljhewrgoh。您應(yīng)該看到我們的“未找到”消息。
添加API端
我們的 vue.js/flask教程的最后一個(gè)例子將是服務(wù)器端API創(chuàng)建和調(diào)度客戶端。我們將創(chuàng)建一個(gè)簡(jiǎn)單的Api,它將從1到100返回一個(gè)隨機(jī)數(shù)。
打開run.py并添加:
from flask import Flask, render_template, jsonify from random import * app = Flask(__name__, static_folder = "./dist/static", template_folder = "./dist") @app.route('/api/random') def random_number(): response = { 'randomNumber': randint(1, 100) } return jsonify(response) @app.route('/', defaults={'path': ''}) @app.route('/<path:path>') def catch_all(path): return render_template("index.html")
首先我導(dǎo)入random庫和jsonify函數(shù)從Flask庫中。然后我添加了新的路由 /api/random來返回像這樣的JSON:
{ "randomNumber": 36 }
你可以通過本地瀏覽測(cè)試這個(gè)路徑: localhost:5000/api/random。
此時(shí)服務(wù)器端工作已經(jīng)完成。是時(shí)候在客戶端顯示了。我們來改變home.vue組件顯示隨機(jī)數(shù):
<template> <div> <p>Home page</p> <p>Random number from backend: {{ randomNumber }}</p> <button @click="getRandom">New random number</button> </div> </template> <script> export default { data () { return { randomNumber: 0 } }, methods: { getRandomInt (min, max) { min = Math.ceil(min) max = Math.floor(max) return Math.floor(Math.random() * (max - min + 1)) + min }, getRandom () { this.randomNumber = this.getRandomInt(1, 100) } }, created () { this.getRandom() } } </script>
在這個(gè)階段,我們只是模仿客戶端的隨機(jī)數(shù)生成過程。所以,這個(gè)組件就是這樣工作的:
現(xiàn)在在主頁上,你應(yīng)該看到前端顯示我們產(chǎn)生的隨機(jī)數(shù)。讓我們把它連接到后端。
為此目的,我將用 axios庫。它允許我們用響應(yīng)HTTP請(qǐng)求并用 Json返回 JavaScript Promise。我們安裝下它:
(venv) cd frontend (venv) npm install --save axios
打開 home.vue再在 <script>部分添加一些變化:
import axios from 'axios' methods: { getRandom () { // this.randomNumber = this.getRandomInt(1, 100) this.randomNumber = this.getRandomFromBackend() }, getRandomFromBackend () { const path = `http://localhost:5000/api/random` axios.get(path) .then(response => { this.randomNumber = response.data.randomNumber }) .catch(error => { console.log(error) }) } }
在頂部,我們需要引用Axios庫。然后有一個(gè)新的方法 getrandomfrombackend將使用Axios異步調(diào)用API和檢索結(jié)果。最后, getrandom方法現(xiàn)在應(yīng)該使用 getrandomfrombackend函數(shù)得到一個(gè)隨機(jī)值。
保存文件,到瀏覽器,運(yùn)行一個(gè)開發(fā)服務(wù)器再次刷新 localhost:8080。你應(yīng)該看到控制臺(tái)錯(cuò)誤沒有隨機(jī)值。但別擔(dān)心,一切都正常。我們得到了 CORS的錯(cuò)誤意味著Flask服務(wù)器API默認(rèn)會(huì)關(guān)閉其他Web服務(wù)器(在我們這里,vue.js App是在 Node.js服務(wù)器上運(yùn)行的應(yīng)用程序)。如果你 npm run build項(xiàng)目,那在 localhost:5000(如Flask服務(wù)器)你會(huì)看到App在工作的。但是,每次對(duì)客戶端應(yīng)用程序進(jìn)行一些更改時(shí),都創(chuàng)建一個(gè)包并不十分方便。
讓我們用打包了CORS插件的Flask,將使我們能夠創(chuàng)建一個(gè)API訪問規(guī)則。插件叫做FlaskCORS,讓我們安裝它:
(venv) pip install -U flask-cors
你可以閱讀文檔,更好的解釋你要使你的服務(wù)器怎么樣使用CORS。我將使用特定的方法,并將**{“origins”: “*”}**應(yīng)用于所有/api/*路由(這樣每個(gè)人都可以使用我的API端)。在run.py加上:
from flask_cors import CORS app = Flask(__name__, static_folder = "./dist/static", template_folder = "./dist") cors = CORS(app, resources={r"/api/*": {"origins": "*"}})
有了這種改變,您就可以從前端調(diào)用服務(wù)端。
更新:
事實(shí)上,如果你想通過Flask提供靜態(tài)文件不需要CORS。感謝Carson Gee的下面的這一招。
這個(gè)主意是這樣的。如果應(yīng)用程序在調(diào)試模式下,它只會(huì)代理我們的前端服務(wù)器。否則(在生產(chǎn)中)只為靜態(tài)文件服務(wù)。所以我們這樣做:
import requests @app.route('/', defaults={'path': ''}) @app.route('/<path:path>') def catch_all(path): if app.debug: return requests.get('http://localhost:8080/{}'.format(path)).text return render_template("index.html")
很優(yōu)雅的魔法:sparkles:!
現(xiàn)在有了一個(gè)完整的全棧**(full-stack) 應(yīng)用程序,用您最喜愛Vue.js 和Flask**技術(shù)構(gòu)建。
后記
最后,我想就如何改進(jìn)這個(gè)解決方案談幾句話。
首先利用CORS,如果你想讓你的API端訪問外部的服務(wù)器。否則的話只需要使用代理服務(wù)器與前端開發(fā)技巧。
另一個(gè)改進(jìn)是避免客戶端硬編碼API路由。也許你需要考慮一些API端點(diǎn)的字典。因此,當(dāng)您更改API路由時(shí),只需刷新一個(gè)字典即可。前端仍然有一個(gè)有效的端點(diǎn)。
通常在開發(fā)過程中,你將至少有2個(gè)終端窗口:一個(gè)是Flask和另一個(gè)是vue.js。在生產(chǎn)中可以擺脫Vue而只單獨(dú)運(yùn)行Node.js服務(wù)器。
源代碼:https://github.com/oleg-agapov/flask-vue-spa
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持創(chuàng)新互聯(lián)。
新聞名稱:使用Vue.js和Flask來構(gòu)建一個(gè)單頁的App的示例
當(dāng)前URL:http://jinyejixie.com/article14/ipjhde.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供定制開發(fā)、網(wǎng)站建設(shè)、網(wǎng)站設(shè)計(jì)、網(wǎng)站制作、靜態(tài)網(wǎng)站、搜索引擎優(yōu)化
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)