Vue.js动态组件 - 模板未显示组件数据

时间:2017-12-25 19:23:55

标签: vue.js

我试图用VueJs建立一个测验游戏,直到现在一切顺利,但现在我开始使用动态组件我在遇到显示数据的问题。

当用户点击开始按钮时,我有一个开始组件(开始视图),我想用实际的测验组件("进行中")替换它。这很顺利。但是,在第二个组件模板中,{{ self.foo }}引用的数据不再显示,没有任何错误消息。

我实施的方式如下:

startComponent:

startComponent = {
    template: '#start-component',
    data: function () {
        return {
            QuizStore: QuizStore.data
        }
    },
    methods: {
        startQuiz: function () {
                this.QuizStore.currentComponent = 'quiz-component';
            }
        }
    }
};

模板:

<script type="x-template" id="start-component">
    <div>
        <button v-on:click="startQuiz()">
            <span>Start Quiz</span>
        </button>
    </div>
</script>

注意:我使用的是x-templates,因为它以某种方式最有意义,其余的应用程序是Python / Flask。但是所有内容都包含在{% raw %}中,因此括号不是问题。

测验组件:

quizComponent = {
    template: '#quiz-component',
    data: function () {
        return {
            QuizStore: QuizStore.data,
            question: 'foo',
    }
};

模板:

<script type="x-template" id="quiz-component">
    <div>
        <p>{{ self.question }}</p>
    </div>
</script>

正如您可能已经看到我使用存储所有状态的QuizStore。

商店:

const QuizStore = {
    data: {
        currentComponent: 'start-component',
    }
};

在主.html中我实现动态组件如下:

<div id="app">
    <component :is="QuizStore.currentComponent"></component>
</div>

那么有效:

  • 显示按钮的“开始”屏幕。
  • 当我点击“开始”按钮时,quizComponent会按预期显示。

什么行不通:

  • QuizComponent模板中的{{ self.question }}数据未显示。并且它不会抛出错误消息。
  • 它也不适用于{{question}}。

我不明白:

  • 如果我首先使用设置QuizStore.currentComponent = 'startComponent'呈现quizComponent,则数据会整齐地显示出来。
  • 如果我切换回<quiz-component></quiz-component>(而不是动态组件),它也能正常工作。
  • 所以似乎问题是this.没有引用当前活动的动态组件 - 所以我猜这是错误的?但话又说回来,我不明白为什么没有错误信息......

我无法弄清问题是什么 - 有人吗?

2 个答案:

答案 0 :(得分:0)

您的父组件可能在某些问题上不了解其子组件,而您的QuizStore构造具有data图层,您在设置currentComponent时不会考虑该图层。

&#13;
&#13;
const startComponent = {
  template: '#start-component',
  data: function() {
    return {
      QuizStore: QuizStore.data
    }
  },
  methods: {
    startQuiz: function() {
      this.QuizStore.currentComponent = 'quiz-component';
    }
  }
};

const QuizStore = {
    data: {
        currentComponent: 'start-component',
    }
};

new Vue({
  el: '#app',
  data: {
    QuizStore
  },
  components: {
    quizComponent: {
      template: '#quiz-component',
      data: function() {
        return {
          QuizStore: QuizStore.data,
          question: 'foo'
        }
      }
    },
    startComponent
  }
});
&#13;
<script src="//cdnjs.cloudflare.com/ajax/libs/vue/2.4.2/vue.min.js"></script>
<script type="x-template" id="start-component">
  <div>
    <button v-on:click="startQuiz()">
            <span>Start Quiz</span>
        </button>
  </div>
</script>

<script type="x-template" id="quiz-component">
  <div>
    <p>{{ question }}</p>
  </div>
</script>

<div id="app">
  <component :is="QuizStore.data.currentComponent"></component>
</div>
&#13;
&#13;
&#13;

答案 1 :(得分:0)

以下工作最终:

我只是将<component :is="QuizStore.currentComponent"></component>包装在父组件(“index-component”)中,而不是直接将其放在主html文件中:

<div id="app">
    <index-component></index-component>
</div>

在index-component中:

<script type="x-template" id="index-component">
    <div>
        <component :is="QuizStore.currentComponent"></component>
    </div>
</script>

也许这一直是正确的方式,或者可能不是,但它现在有效:)非常感谢Roy的帮助!