最近在项目开发中遇到这样一个问题:后端使用的是 Python Flask 框架,渲染方式为后端渲染。而前端使用的 Vue 技术栈。页面的显示经过后端渲染生成的 dist 包中的 index.html
文件来实现。因为项目的历史包袱,后端须要传值给前端,前端须要在某些组件中使用后端渲染传递过来的值。可是有一点略坑:后端渲染时只能识别 vue 生成的 index.html,在 vue 中是没法直接经过 {{ 参数名 }}
的方式直接获取传入参数 。本文对于这个问题给出三种可行的解决方案。javascript
Python Flask 框架中使用 render_template
函数来渲染对应的模板,该函数的第二个参数就是传入的参数。示例代码以下:html
@app.route('/test')
def test_pass_parm():
parm_value = 'I am value from backend'
return render_template('test/dist/index.html', parm_value)
复制代码
上面代码是一个 Flask 中比较常规的写法。parm_value 是后端要传给 index.html 模板中的值, index.html 是 Vue 中生成的打包文件。在 index.html 中,可使用 {{ parm_value }}
在模板中展现后端传入的值。前端
PS: Python Flask 渲染时,可能会由于 {{ }} 符号缘由,与 vue 的插值语法有冲突,后端没法识别并正常渲染,须要修改 Vue 的分隔符 delimiters 项来避免后端渲染错误。vue
经过 index.html 中的 title 渲染值,在 vue 组件中经过 document.title
来进行获取。java
在 vue 工程中的 index.html 中设置 title 以下:python
<head>
<meta chartset=utf-8>
<title>{{parm_value}}</title>
</head>
复制代码
当目标打包文件 index.html 被渲染成功后,param_value 就会被 flask 识别出来,渲染成传入的值。在 vue 组件中,能够进行如下的处理:flask
mounted(){
//1. 经过 document.title 获取值
this.pValue = document.title
//2. 从新设置 document.title 为正常的网页 title
document.title = "测试网页标题"
}
复制代码
在 vue 组件中,pValue
就是后端渲染传入的值了。后端
在 index,html 中添加一个与 app 同级的 dom 节点bash
<html>
<head>
<meta>
<title></title>
</head>
<body>
<input id="test-dom" type="hidden" value="{{parm_value}}">
<div id="app"></div>
</body>
</html>
复制代码
也许你会问一个问题,为何不将 dom 结点放在 div#app
内部?答案很简单:由于生成的 dom 节点若在 div#app
内,运行时会被替换掉,在 vue 组件中没法获取到对应的 dom 节点。app
在 vue 组件中处理:
mounted() {
// 1. 获取对应的 dom 节点
let testDom = document.getElementById('test-dom')
// 2. 获取 dom 节点对应的值
let pValue = testDom.value
}
复制代码
在 index.html 中新增 script 标签进行渲染,经过 window.xxx 进行获取
<html>
<head>
<meta>
<title></title>
</head>
<body>
<input id="test-dom" type="hidden" value="{{parm_value}}">
<div id="app"></div>
<script> window.pValue = '{{parm_value}}' </script>
</body>
</html>
复制代码
在 vue 组件中,经过 window.pValue
直接获取渲染值。
以上,就是 Vue 前端工程中获取后端渲染方式传递值的三种方式。我的推荐第2、三种方式,孰优孰劣,可斟酌使用。因为项目是从后端渲染模板的方式逐渐升级为先后端分离的方式,在此过程当中遇到了这个问题,梳理并总结出来,供后续查阅,避免再次入坑。