将flask变量直接传递给vue的最佳方法是什么?

时间:2017-05-26 20:55:47

标签: javascript python variables flask vue.js

我正在开发一个带有烧瓶服务器和前端vue.js的vizualisation应用程序。

关于这个主题的类似问题寻找一种方法使vue.js和flask变量语法不会像显示here那样进入冲突。

在我的情况下,我想知道是否有任何方法直接使用Flask render_template方法发送变量vue.js变量data.d。

    var app = new Vue({
      el: '#app',
      data: {
        'd': {{Flask-variable}}
      },
})

这是代码

烧瓶

import os
import flask
import json
from flask import Flask, render_template, request, redirect, url_for
from script_python import kernel as K


def App():
    # Initialize the Flask application
    app = Flask(__name__)
    app.config.from_object('marianaViz.config.ConfigClass')

    #return index.html on load
    @app.route('/')
    def index():
        d = [{'x':1, 'y':0, 'z': 1},{'x':1, 'y':0, 'z': 2}]
        return flask.render_template("histogram.html",d= flask.jsonify(**K.JSONResponse(data = d,error=False,message='')))

    return app

JS

var app = new Vue({
  el: '#app',
  data: {
    'd':{{ d.data|tojson|safe}},
  },
  created:function(){
        this.drawHistogram(d),
      },
  methods:{
  // Called when the Visualization API is loaded.
    drawHistogram: function(){
      var data = null;
      var graph = null;
      var self = this;


      // Create and populate a data table.
      console.log(d);
        data = self.d;
        //data = [{x:1, y:0, z: 1},{x:1, y:0, z: 2},{x:2, y:0, z: 3},{x:3, y:0, z: 2},{x:4, y:0, z: 1},{x:5, y:0, z: 1},{x:6, y:0, z: 2},{x:7, y:0, z: 3},{x:8, y:0, z: 2},{x:9, y:0, z: 1},{x:10, y:0, z: 1},{x:11, y:0, z: 2},{x:12, y:0, z: 3},{x:13, y:0, z: 2},{x:14, y:0, z: 1},{x:15, y:0, z: 1},{x:16, y:0, z: 2},{x:17, y:0, z: 3},{x:18, y:0, z: 2},{x:19, y:0, z: 1}];

        // create some nice looking data with sin/cos

        /*
        function custom(x, y) {
        return (-Math.sin(x/Math.PI) * Math.cos(y/Math.PI) * 10 + 10);
        }
        var steps = 4;  // number of datapoints will be steps*steps
        var axisMax = 15;
        var axisStep = axisMax / steps;
        for (var x = 0; x <= axisMax; x+=axisStep) {
          for (var y = 0; y <= axisMax; y+=axisStep) {
            var z = custom(x,y);
              data.push({x:x, y:0, z: z});
          }
          console.log(data);
        }
        */

        // specify options
        var options = {
          width:  '300px',
          height: '300px',
          style: 'bar',
          xBarWidth: 0.5,
          yBarWidth: 0.5,
          showPerspective: true,
          showGrid: true,
          showShadow: false,
          "showYAxis":false,
          "xLabel":'',
          "zLabel":'',
          cameraPosition: {
              horizontal: 0*3.14,
              vertical: 0*3.14,
              distance: 1.8
            },
            legendLabel: '',
          keepAspectRatio: true,
          verticalRatio: 0.5,
          "backgroundColor":'black',
          "showLegend": true,
          "xCenter":'50%',
        };

        var camera = graph ? graph.getCameraPosition() : null;

        // create our graph
        var container = document.getElementById('histogram');
        graph = new vis.Graph3d(container, data, options);

        if (camera) graph.setCameraPosition(camera); // restore camera position


  }

    }
})

HTML

<!doctype html>
<html>
    <head>
    <!--Vuejs-->
     <script type="text/javascript" src="{{url_for ('static',filename='js/vue.js')}}"></script>
    <!--css-->
    <link href="{{url_for ('static',filename='css/disp.css')}}" rel="stylesheet" type="text/css"/>
    <!--Vis visualisation lib-->
    <link href="https://cdnjs.cloudflare.com/ajax/libs/vis/4.19.1/vis.min.css" rel="stylesheet" type="text/css"/>
    <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/vis/4.19.1/vis.min.js"></script>
    <!--<script type="text/javascript" src="/front/lala_web/vis.js"></script>-->

    </head>

    <body>

        <div id="app">
            <h2>Histogram:</h2>
            <div id="histogram"></div>
        </div>
    </body >
        <!--display.js-->
         <script type="text/javascript" src="{{url_for ('static',filename='js/histogram.js')}}"></script>

</html>

2 个答案:

答案 0 :(得分:1)

您有许多选项,我将向您展示4适用于简单数据类型(int,字符串等),并且需要更多努力,您还可以使它们适用于更复杂的数据类型(数组,对象等)

  1. 使用内联JavaScript
  2. 只需在脚本标记中分配变量

    <script type="text/JavaScript"> 
     #some var from flask
      var d_var = "{{somevalue}}" 
     </script>
    

    然后在你的vue脚本中,你可以做到

    var vm = new Vue({
      el: '#demo',
      data: {
      d: d_var
      ...
    

    其余步骤涉及将变量分配给DOM元素的属性(例如隐藏输入)

    1. 使用jQuery
    2. 在主vue dom元素中创建一个隐藏输入,其值设置为flask变量

      <input name="d_elem" type="hidden" value="{{somevalue}}" id="d_elem" />
      

      然后在您的vue脚本中,您现在可以

      var d_var = $("#d_elem").val(); 
      var vm = new Vue({
        el: '#demo',
        data: {
        d: d_var
        ...
      
      1. 使用普通的旧getElementById
      2. 如果你遭受JS库疲劳,只需像以前一样创建隐藏的输入,但这次你做

         var d_var =  document.getElementById("d_elem").value;
         var vm = new Vue({
          el: '#demo',
          data: {
          d: d_var
          ...
        
        1. 使用vm。$ refs
        2. 使用ref属性

          创建隐藏输入
          <input name="d_elem" type="hidden" value="{{somevalue}}" ref="d_elem" />
          

          在像

          这样的vue实例中访问它
          var d_var = this.$refs.d_elem.value ;
          

答案 1 :(得分:0)

我认为你可以做点什么

'd':{{ flask_variable|tojson|safe }}

粗糙你的变量需要是json serializeable

您可能必须将json重新解析为js

JSON.parse('{{ flask_variable|tojson|safe }}')(至少类似的东西),它必须是一个可以转换为json的对象(即python类可能不会工作......字符串和数字应该)