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博客

相关推荐
网易独家音乐人Mike Zhou2 小时前
【卡尔曼滤波】数据预测Prediction观测器的理论推导及应用 C语言、Python实现(Kalman Filter)
c语言·python·单片机·物联网·算法·嵌入式·iot
安静读书2 小时前
Python解析视频FPS(帧率)、分辨率信息
python·opencv·音视频
活宝小娜3 小时前
vue不刷新浏览器更新页面的方法
前端·javascript·vue.js
程序视点3 小时前
【Vue3新工具】Pinia.js:提升开发效率,更轻量、更高效的状态管理方案!
前端·javascript·vue.js·typescript·vue·ecmascript
coldriversnow3 小时前
在Vue中,vue document.onkeydown 无效
前端·javascript·vue.js
小二·4 小时前
java基础面试题笔记(基础篇)
java·笔记·python
刚刚好ā4 小时前
js作用域超全介绍--全局作用域、局部作用、块级作用域
前端·javascript·vue.js·vue
小喵要摸鱼5 小时前
Python 神经网络项目常用语法
python
会发光的猪。7 小时前
css使用弹性盒,让每个子元素平均等分父元素的4/1大小
前端·javascript·vue.js
一念之坤7 小时前
零基础学Python之数据结构 -- 01篇
数据结构·python