Flask template+Vue +项目中include引入其他模版(其他模版也会用到vue)的使用探索
项目背景是:团队的历史项目,是flask tmeplate写的前段页面。然后我在一个页面A.html中引入了vue文件,使用了vue+element_ui技术。现在想在此A页面中插入另外一个页面B.html的内容(试图tab分开),因为入口只有A页面作为入口,想要在B.html中实现不同与A的功能。
尝试1,html文件中可以存在多个vue实例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="{{ url_for('static', filename='js/vue.js') }}" type="text/javascript"></script>
<script src="{{ url_for('static', filename='js/axios.min.js') }}" type="text/javascript"></script>
<!-- 引入样式 -->
<link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
<!-- 引入组件库 -->
<script src="https://unpkg.com/element-ui/lib/index.js"></script>
</head>
<body>
{{done}}
<div id="app">
<h1>
{{ "{{" }} msg {{ "}}" }}</h1>
<div>hello</div>
</div>
<div id="app-body">
<h4>
{{ "{{" }} title {{ "}}" }}</h4>
<div>hello</div>
</div>
<div class="app-footer">
<h4>
{{ "{{" }} footer {{ "}}" }}</h4>
<div>hello</div>
</div>
<script>
const vm = new Vue({
el: '#app',
data: function () {
return {
msg: "前段vue使用",
}
}
});
</script>
<script>
const vmBody = new Vue({
el: '#app-body',
data: function () {
return {
title: "vue实例2"
}
}
});
</script>
<script>
const vmFooter = new Vue({
el: '.app-footer',
data: function () {
return {
footer: "vue实例3",
}
}
});
</script>
</body>
</html>
前端:
但是全都写到一起,虽然可以分为两个vue实例来处理,但是不想两个功能的html代码和vue代码参和在一个文件中,导致一个文件太大太乱。
尝试2,可以通过 flask template的jinjia语法 include来引入外部模块 (注意此种用法不是很大众,出现了问题,并未解决,急需大牛帮我看看问题所在,不胜感激!!)
比如在A.html中的某个位置
{% include './new_module/B.html' %}
导入B的内容。A.html内容如下:
div id="order">
<el-tabs type="border-card" v-model="active_tab_name">
<el-tab-pane name="pc_side">
<span slot="label" class="order_tab_title"><i class="el-icon-s-platform
"></i> A部门工单申请</span>
<div id="main_index">
A页面的主要内容
</div>
</el-tab-pane>
<el-tab-pane name="">
<span slot="label" class="order_tab_title"><i class="el-icon-search
"></i> B部门工单申请</span>
{% include './order_manage/param_test.html' %}
</el-tab-pane>
</el-tabs>
注意:导入的内容是无法解析<script>标签的。若B.html的内容如下存在script标签。
<div id="param_order_search">
<div>
<el-form ref="form" :model="form" label-width="80px">
<el-form-item label="活动名称">
<el-input v-model="form.name"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="is_test_method()">立即创建sss</el-button>
<el-button type="primary" @click="bye_msg='bye2bye2'">立即创建222</el-button>
<el-button>取消</el-button>
</el-form-item>
</el-form>
</div>
<div>
再见再见 {{"{{"}} bye_msg {{"}}"}}
</div>
</div>
<script>
var create_param_search = new Vue({
el: "#param_order_search",
data: function () {
return {
sub_msg: "感谢阅读",
bye_msg: "bye bye",
form:{
name:"参数名称"
}
}
},
mounted:function (){
console.log("create_param_search mounted")
this.is_test_method()
},
methods:{
is_test_method(){
console.log("is_test_method")
}
}
})
</script>
出现的错误如下:
vue.js:634 [Vue warn]: Error compiling template:
Templates should only be responsible for mapping the state to the UI. Avoid placing tags with side-effects in your templates, such as <script>, as they will not be parsed
于是想了迂回的方法:使用 template 的jinjia方法:macro
如是B.html变为:
<div id="param_order_search">
<div>
<el-form ref="form" :model="form" label-width="80px">
<el-form-item label="活动名称">
<el-input v-model="form.name"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="is_test_method()">立即创建sss</el-button>
<el-button type="primary" @click="bye_msg='bye2bye2'">立即创建222</el-button>
<el-button>取消</el-button>
</el-form-item>
</el-form>
</div>
<div>
再见再见 {{"{{"}} bye_msg {{"}}"}}
</div>
</div>
{% macro create_param_search() %}
var create_param_search = new Vue({
el: '#param_order_search',
data: function () {
return {
sub_msg: "感谢阅读",
bye_msg: "bye bye",
form:{
name:"参数名称"
}
}
},
template:"#tem",
mounted:function (){
console.log("create_param_search mounted")
is_test_method()
},
methods:{
is_test_method(){
console.log("is_test_method")
}
}
})
{% endmacro %}
在A.html的scipt中(与第一个vue实例一起的script中)
于是A.html的script变为:
<script>
{% from "./order_manage/param_test.html" import create_param_search %}
{{ create_param_search() }}
var order= new Vue({
el: "#order",
data: {
........
</script>
页面也能正常加载
查看页面源码,发现B.hmtl的代码已经加载进入A.html中,但是控制台查看元素中button中是没有绑定相关click代码的。
<el-tab-pane >
<span slot="label" class="order_tab_title"><i class="el-icon-search
"></i> B部门工单申请</span>
<div id="param_order_search">
<div>
<el-form ref="form" :model="form" label-width="80px">
<el-form-item label="活动名称">
<el-input v-model="form.name"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="is_test_method()">立即创建sss</el-button>
<el-button type="primary" @click="bye_msg='bye2bye2'">立即创建222</el-button>
<el-button>取消</el-button>
</el-form-item>
</el-form>
</div>
<div>
再见再见 {{ bye_msg }}
</div>
</div>
......
<script>
var create_param_search = new Vue({
el: '#param_order_search',
data: function () {
return {
sub_msg: "感谢阅读",
bye_msg: "bye bye",
form:{
name:"参数名称"
}
}
},
mounted:function (){
console.log("create_param_search mounted")
is_test_method()
},
methods:{
is_test_method(){
console.log("is_test_method")
}
}
})
var order= new Vue({
el: "#order",
data: {
......
</script>
但是出现了问题:方法无法调用!!!至今没找到解决办法
点击页面的按钮,方法没有被调用,隐约觉得原因是因为include加载模块后渲染没有识别vue的代码写法丢弃了。但是为啥能识别elment_ui的写法呢?不解....
尝试3,使用import导入script vue代码,然后vue实例加载template模版
此种方法B.html内容是:
<template id="param_order_search">
<div >
<div>
<el-form ref="form" :model="form" label-width="80px">
<el-form-item label="活动名称">
<el-input v-model="bye_msg"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="is_test_method()">立即创建sss</el-button>
<el-button type="primary" @click="bye_msg='bye2bye2'">立即创建222</el-button>
<el-button>取消</el-button>
</el-form-item>
</el-form>
</div>
<div>
再见再见 {{"{{"}} bye_msg {{"}}"}}
</div>
</div>
</template>
{% macro create_param_search() %}
var create_param_search = new Vue({
el: '#param_order_search_top',
data: function () {
return {
sub_msg: "感谢阅读",
bye_msg: "bye bye",
form:{
name:"参数名称"
}
}
},
mounted:function (){
console.log("create_param_search mounted")
this.is_test_method()
},
methods:{
is_test_method(){
console.log("is_test_method")
}
}
})
{% endmacro %}
A.html中展示B内容的区域的代码为:
<div id="param_order_search_top">
下面是挑战性内容哦!!
<create_param_search></create_param_search>
</div>
.......
<script>
{% from "./order_manage/param_test.html" import create_param_search %}
{{ create_param_search() }}
var order= new Vue({
el: "#order",
data: {
.....
结果就是报错:
Unknown custom element: <create_param_search> - did you register the component correctly? For recursive components, make sure to provide the "name" option.
(found in <Root>)
应该是 模版渲染+vue解析 时机和import代码解析时机是有时差的,所以导致没发现import的vue代码
尝试4:目前看下来是可行的。使用iframe来加载B.html到A.html中,b。html中写html代码及js代码。
可参考我的另外一篇博客:
Flask template中使用iframe-CSDN博客