使用 flask 和 vue-cli 脚手架,开发 vue3.x 版本的 python 与 typeScript web 项目
目前
vue3.x版本已经出来很久了,已经有不少UI库开发者和公司在使用3.x版本了。
代码地址 github地址:github.com/18055975947… 码云地址:gitee.com/guoqiankun/…
一、创建项目
1. 先用 pyCharm 创建 python-flask-vue-web 项目
文件目录
.
├── app.py
├── static
├── templates
└── venv
2. 在文件夹中 使用 vue create vue-web 创建 vue3.x 版本项目
.
├── app.py
├── static
├── templates
├── venv
└── vue-web
3. 添加 vue.config.js 文件
暂不往里面加东西
module.exports = {}
4. 启动项目
cd vue-web
yarn serve
5. 修改 vue.config.js 文件
我们开发 flask web 项目,最后通过 render_template 来导入文件,但是在 vue 项目中 通过 yarn run build 生成的文件 在 vue-web 文件中,所以配置一个 outputDir 和 indexPath
-
outputDir
- Type:
string - Default:
'dist' - 当运行
vue-cli-service build时生成的生产环境构建文件的目录。
- Type:
-
indexPath
- Type:
string - Default:
'index.html' - 指定生成的
index.html的输出路径 (相对于outputDir)。也可以是一个绝对路径。
- Type:
module.exports = {
outputDir: '../static',
indexPath: '../templates/index.html'
}
为什么要配置 outputDir 和 indexPath
- 我们使用
pycharm创建的项目从上面的 使用tree展示的文件夹目录来看,有templates模版文件夹 和static资源文件夹 - 使用的
vue-cli3.x及以上版本生成的项目打包之后 没有static文件夹,只有js和css文件夹,而我们通过Flask引入静态资源的路径只能有一个,所以需要给js、css一个父文件夹
6、yarn run build 打包
tree -I "venv|*node_modules*" -L 2
-I 不展示 venv 目录 和 node_modules 目录
-L 2 展示两个层级
.
├── app.py
├── static
│ ├── css
│ ├── favicon.ico
│ ├── img
│ └── js
├── templates
│ └── index.html
└── vue-web
├── package.json
├── public
├── src
├── tsconfig.json
├── vue.config.js
└── yarn.lock
此时可以发现,index.html 和 js、css、img 都在指定的文件夹中了
二、预览项目
我们通过 yarn run build 打包项目,也在对应的文件夹内生成了文件
此时,回到我们的 app.py 文件中,引入 index.html
from flask import Flask, render_template
app = Flask(__name__)
@app.route('/')
def hello_world():
return render_template('index.html')
if __name__ == '__main__':
app.run()
运行此 python 文件
可以看到
Running on http://127.0.0.1:5000/
浏览器打开发现报错,js、css 文件404,只有第一个 html 文件可以找到
而在 pyCharm 的控制台中也是显示404
三、修改项目
1. 修改 vue.config.js 文件
文件报错是 404,意思是路径不对
我们在 vue.config.js 中配置 assetsDir 项
- assetsDir
- Type:
string - Default:
'' - 放置生成的静态资源 (js、css、img、fonts) 的 (相对于 outputDir 的) 目录。
- Type:
module.exports = {
outputDir: '../static',
indexPath: '../templates/index.html',
assetsDir: 'static/'
}
配置 assetsDir 项的目的是把 静态资源以及生成的 js、css、img等加载到 static 文件夹下
yarn run build 打包
此时 python-flask-vue-web 中 static 文件夹内容
tree static/ 展示 static 文件夹下的内容
static/
├── favicon.ico
└── static
├── css
│ └── app.ca79b516.css
├── img
│ └── logo.82b9c7a5.png
└── js
├── about.71b95ce9.js
├── about.71b95ce9.js.map
├── app.f47513f4.js
├── app.f47513f4.js.map
├── chunk-vendors.24202124.js
└── chunk-vendors.24202124.js.map
2. 修改 app.py 文件
在 Flask 创建的 app 中添加静态资源目录
from flask import Flask, render_template
app = Flask(__name__,
static_folder='./static/static')
@app.route('/')
def hello_world():
return render_template('index.html')
if __name__ == '__main__':
app.run()
3. 运行 python 文件
重新打开 http://127.0.0.1:5000/
可以发现,此时 js、css、img 引入都正常了,页面也可以正常显示了,但是此时有一个 favicon.ico 404...
所以此时到了对静态资源的项目引入
四、对项目添加静态资源
1. favicon.ico 路径修改
- 先在
vue-web/public/文件夹下 创建static文件夹 - 把
favicon.ico放到static文件夹中
vue-web/public/
├── index.html
└── static
└── favicon.ico
- 修改
vue-web/public/文件夹下的index.html文件,把favicon.ico的引入路径修改下
<link rel="icon" href="static/favicon.ico">
yarn run build打包vue项目- 重新运行
app.py文件 - 浏览器重新打开
http://127.0.0.1:5000/
此时 favicon.ico 可以正常加载
2. 对项目添加一个静态 js ,例如 jquery.js
- 把
jquery.js放到static文件夹中
vue-web/public/
├── index.html
└── static
├── favicon.ico
└── jquery.js
index.html文件中引入jquery.js
<script src="static/jquery.js"></script>
- 在
home.vue中打印$
<script lang="ts">
import { defineComponent } from 'vue'
import HelloWorld from '@/components/HelloWorld.vue' // @ is an alias to /src
declare global {
interface Window {
'$': any;
}
}
export default defineComponent({
name: 'Home',
components: {
HelloWorld
},
mounted () {
console.log(window.$)
}
})
</script>
在我们运行的 vue 前端项目中可以看到日志
yarn run build打包- 重新运行
app.py文件,打开python的http://127.0.0.1:5000/查看页面
此时,favicon.ico 和 静态资源的路径引入就正确了,项目可以正常开发了
3. 到此,正常的 vue 项目就可以开发
前端按照 vue 正常开发模式开发页面即可,后端 python 按照 python 代码来写即可。
五、前后端 ajax 请求
前端 web 页面需要调用 python 中的接口,此也是前后端分离中的最重要的一点
1. app.py 中写入一个 返回 随机数的接口 /api/getRandomNum
from flask import Flask, render_template, jsonify
import random
app = Flask(__name__,
static_folder='./static/static')
@app.route('/')
def hello_world():
return render_template('index.html')
@app.route('/api/getRandomNum')
def get_random_num():
res = {
'getRandomNum': random.randint(1, 100)
}
return jsonify(res)
if __name__ == '__main__':
app.run()
重新运行 app.py 文件
2. vue 项目 引入 axios
vue中yarn add axios- 在
main.ts中引入axios
import axios from 'axios'
const app = createApp(App)
app.provide('axios', axios)
- 在
home.vue中使用axios进行请求
<script lang="ts">
import { defineComponent, inject } from 'vue'
import HelloWorld from '@/components/HelloWorld.vue' // @ is an alias to /src
declare global {
interface Window {
'$': any;
}
}
export default defineComponent({
name: 'Home',
components: {
HelloWorld
},
setup () {
const axios: any = inject('axios')
axios.get('http://localhost:5000/api/getRandomNum').then((res: object) => {
console.log(res)
}).catch((e: any) => {
console.log(e)
})
}
})
</script>
yarn serve打开页面发现,请求报错,跨域报错
3. 接口跨域问题解决
A Flask extension for handling Cross Origin Resource Sharing (CORS), making cross-origin AJAX possible.
Flask扩展,用于处理跨源资源共享(CORS),使得跨源AJAX成为可能。
pip install flask_corsapp.py引入flask_cors- 跨域处理
from flask import Flask, render_template, jsonify
from flask_cors import CORS
import random
app = Flask(__name__,
static_folder='./static/static')
CORS(app)
@app.route('/')
def hello_world():
return render_template('index.html')
@app.route('/api/getRandomNum')
def get_random_num():
res = {
'getRandomNum': random.randint(1, 100)
}
return jsonify(res)
if __name__ == '__main__':
app.run()
- 重新运行
app.py文件 - 刷新
vue项目
可以看到,接口已经可以正常请求了,正常返回了。
到此,前后端项目都可以正常开发了,ajax 也可以正常请求
六、项目打包并运行
yarn run build打包vue前端项目app.py文件运行- 打开
http://127.0.0.1:5000/#/查看项目
代码地址
- github地址:github.com/18055975947…
- 码云地址:gitee.com/guoqiankun/…