如何使用 $nextTick 在 vue.js 中呈现 Plotly 图表

How to render Plotly charts in vue.js with $nextTick

我正在尝试创建一个搜索引擎,用来自 plot.ly 的图表回答问题。但是一次只能显示一张图表。

我正在尝试使用 $nextTick 来解决它,但没有成功。

这是我的引擎的等效代码


<template>
<!-- eslint-disable -->
  <v-container>
    <v-layout text-xs-center wrap >
      <v-flex ref="search" id="search_bar" xs12>
        <img src="../../logo.png" height="200"><img>
        <div>
          <v-text-field ref= "search_bar" v-model="searchText" @keyup.enter="search" solo append-icon="search" hide-details single-line> </v-text-field> 
        </div>

      </v-flex>

      <v-flex ref="cards" id="cards" xs12>
          <v-container grid-list-md>

            <v-layout align-center justify-space-around row="2" fill-height id="layout">
                <v-flex auto v-for = "item in vetRespostas" :key="item.id">
                  {{item.id}}
                  <textCard v-if= "item.cardType == 'text' " :textProps = "item.text" ></textCard>

                  <graphCard v-if= "item.cardType == 'graph' " :dataProps = "item.data" :layoutProps = "item.layout"></graphCard>

                  <tableCard v-if= "item.cardType == 'table' " :textProps = "textMock"></tableCard>

                </v-flex>


            </v-layout>

          </v-container> 
      </v-flex>

    </v-layout>
  </v-container>
</template>

<script>
/* eslint-disable */


import Plots_sitop from '../services/plots_sitop'
import tableCard from '../components/tableCard'
import graphCard from '../components/graphCard'
import textCard from '../components/textCard'

  export default({  
    components: {
      graphCard,
      tableCard,
      textCard
    },

    data() {
      return {

        searchText: '', 
        vetRespostas: [],

        quests: [{

          quest1: [{
            pergunta: 'How many Keanu Reeves movies are 5 star?',

            resposta: [
              // primeiro card 
              {
                id: 1,
                cardType: "text",
                text: "All of them"
              },

              // segundo card
              {
                id: 2,
                cardType: "graph",
                data: [{
                  x: ['Matrix','Point Break', 'Matrix Reloaded', 'John Wick', 'Jonh Wick 2','John Wick 3', 'Matriz Revoluntion', '47 Ronin', 'Dracula'],
                  y: [5,4,1,1,2,5,4,3,6],
                  type: "bar",
                  marker: {
                    color: ['rgb(0,140,69)','rgb(192,192,192)','rgb(192,192,192)','rgb(192,192,192)','rgb(192,192,192)','rgb(192,192,192)','rgb(192,192,192)','rgb(192,192,192)','rgb(192,192,192)']
                  }
                }],
                layout: {
                  title: "title",
                  xaxis: {
                    title: "x axys",
                    showgrid: false,
                    zeroline: false
                  },
                  yaxis: {
                    title: 'y axys',
                    showline: false,

                  }
                }
              },
              // terceiro card
              {
                id: 3,
                cardType: "graph",
                data: [{
                  x: [2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018],
                  y: [1, 2, 4, 5, 7, 3, 4, 5, 5],
                  type: "line",
                  marker: {
                    color: ['rgb(192,192,192)','rgb(192,192,192)','rgb(192,192,192)','rgb(192,192,192)','rgb(192,192,192)','rgb(192,192,192)','rgb(192,192,192)','rgb(192,192,192)','rgb(0,140,69)']
                  }
                }],
                layout: {
                  title: "title",
                  xaxis: {
                    title: "title",
                    showgrid: false,
                    zeroline: false
                  },
                  yaxis: {
                    title: 'y axys',
                    showline: false,

                  }
                }
              },
              // quarto card
              {
                id: 4,
                cardType: "graph",
                data: [{
                  x: ['1', '2', '3', '4','5'],
                  y: [5, 2, 2, 3, 1],
                  type: "bar",
                  marker: {
                    color: ['rgb(0,140,69)','rgb(192,192,192)','rgb(192,192,192)','rgb(192,192,192)','rgb(192,192,192)']
                  }
                }],
                layout: {
                  title: "title",
                  xaxis: {
                    title: "y axys",
                    showgrid: false,
                    zeroline: false
                  },
                  yaxis: {
                    title: 'x axys',
                    showline: false,

                  }
                }
              }
            ],

          }],


          quest2: [{
            pergunta: 'How many Keanu Reeves movies are 5 star?',

            resposta: [

              {
                id: 1,
                cardType: "text",
                text: "Keanu Charles Reeves is a Canadian actor and musician."
              },


              {
                id: 2,
                cardType: "graph",
                data: [{
                  x: ['Matrix','Matrix 2', 'Matrix 3', 'Point Break', 'John Wick','John Wick 2', 'John Wick 3', 'Constantine', '47 Ronin'],
                  y: [12,20,5,11,21,23,9,23,12],
                  type: "bar",
                  marker: {
                    color: ['rgb(0,140,69)','rgb(192,192,192)','rgb(192,192,192)','rgb(192,192,192)','rgb(192,192,192)','rgb(192,192,192)','rgb(192,192,192)','rgb(192,192,192)','rgb(192,192,192)','rgb(192,192,192)']
                  }
                }],
                layout: {
                  title: "title",
                  xaxis: {
                    title: "xaxys",
                    showgrid: false,
                    zeroline: false
                  },
                  yaxis: {
                    title: 'y axys',
                    showline: false,
                  }
                }
              },
              {
                id: 3,
                cardType: "graph",
                data: [{
                  x: ['2001','2002','2003','2004','2005'],
                  y: [1, 2, 14, 5, 12],
                  type: "line",
                  marker: {
                    color: ['rgb(0,140,69)','rgb(0,140,69)','rgb(0,140,69)','rgb(0,140,69)','rgb(0,140,69)']
                  }
                }],
                layout: {
                  title: "title",
                  xaxis: {
                    title: "x",
                    showgrid: false,
                    zeroline: false
                  },
                  yaxis: {
                    title: 'y',
                    showline: false,
                  }
                }
              },
              // quarto card 2 mock
              {
                id: 4,
                cardType: "graph",
                data: [{
                  x: ['NS-38', 'P-22', 'NS-14', 'NS-28','P-15'],
                  y: [2, 4, 3, 2, 1],
                  type: "bar",
                  marker: {
                    color: ['rgb(192,192,192)','rgb(192,192,192)','rgb(192,192,192)','rgb(192,192,192)','rgb(192,192,192)']
                  }
                }],
                layout: {
                  title: "title",
                  xaxis: {
                    title: "x",
                    showgrid: false,
                    zeroline: false
                  },
                  yaxis: {
                    title: 'y',
                    showline: false,
                  }
                }

              }
            ]
          }]
        }],
      }
    },

    methods: {

      getResposta: function(){
        var token = localStorage.getItem('token');

        var data_request = {
          'ambiguity_solved':{},
          'has_ambiguity':false,
          'request': this.searchText
        };

        if(token == null){
          Plots_sitop.getToken().then(response => {
            token = response.data.access_token
            localStorage.setItem('token', token)
          })
        }
        let headers = {'Authorization': 'Bearer ' + token, 'Content-Type' : 'application/json'};
        Plots_sitop.postResposta(data_request, {headers}).then(
          response => {

          }, error => {
            // Error
            if (error.response.status == 401){
              Plots_sitop.getToken().then(response => {
                token = response.data.access_token
                localStorage.setItem('token', token)
                this.getResposta()
              })
            }
          })
      },

      // Função utilizada quando os dados estão mockados

      search: function(){ 
        this.$refs.search.style.height = "auto";

        var searchText = this.searchText; 
        var result = false;  
        this.vetRespostas = []

        for(var i in this.quests[0]){
          if(searchText == this.quests[0][i][0].pergunta){
            result = true;
             this.vetRespostas = this.quests[0][i][0].resposta;
            console.log(this.vetRespostas)
        }  
      }

      if(result == false){
        console.log('deu erro')
        // this.$refs.erro.style.display = "inline";
      }
    }
  }
})
</script>

<style>
  #layout{
    flex-direction: row;
  }
  #search{
    height: 80vh;
    display: flex;
    flex-direction: column;
    justify-content: center;
  }
  #card, #plot_1, #erro, #plot_2, #plot_3{
    display: none;
  }

</style>

这是我的组成部分:

<template>
    <v-flex>
        <v-card id = "plot" class="d-flex align-center" light height="400"></v-card>
    </v-flex>
</template>

<script>
import Plotly from 'plotly.js'

export default {
    data(){
        return{

            data: [{
                x: false,
                y: false,
                type: false
            }],

            layout: {
                title: false,
                xaxis:{
                    title: false,
                    showgrind: false,
                    zeroline: false
                },
                yaxis: {
                    title: false,
                    zeroline: false
                }
            },
        }
    },
    props: ['dataProps', 'layoutProps'],

    mounted (){

      this.data = this.dataProps

      this.layout = this.layoutProps

      Plotly.newPlot('plot',this.data,this.layout)
    }
}
</script>

<style>

</style>


<template>
        <v-flex>       
            <v-card  class="mx-auto"  dark v-model='text' color="rgb(0,140,69)" height="400">
                <v-card-text class="display-2 text-xs-center font-weight-black"> {{text}}</v-card-text>  
            </v-card>
        </v-flex>  
</template>

<script>
export default {
  data(){
      return {
          text: ''
      }
  },
  props: ['textProps'],
  mounted(){
      this.text = this.textProps
  }

}
</script>

<style>

</style>


我尝试在我的组件上这样做:


 mounted (){
        this.$nextTick(() => { 
        this.data = this.dataProps 

        this.layout = this.layoutProps 

        Plotly.newPlot('plot',this.data,this.layout) });
    }

但是没有用。

我在我的 id 上使用 V-bind 解决了这个问题。

感谢@skirtle 的帮助。