简体   繁体   English

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

[英]Vue.js Dynamic Component - Template not showing components data

I'm trying to build a quiz-game with VueJs and up until now everything worked out smoothly, but now that I'm started using dynamic components I'm running into issues with displaying the data. 我正在尝试使用VueJs构建测验游戏,直到现在一切都顺利进行,但是现在我开始使用动态组件 ,因此在显示数据时遇到了问题。

I have a start component (Start View) that I want to be replaced by the actual Quiz component ("In Progress") when the user clicks on the start button. 我有一个启动组件(“启动视图”),当用户单击“启动”按钮时,我希望将其替换为实际的“测验”组件(“进行中”)。 This works smoothly. 这样可以顺利进行。 But then, in the second components template, the data referenced with {{ self.foo }} does not show up anymore, without any error message. 但是,在第二个组件模板中,用{{ self.foo }}引用的数据不再显示,没有任何错误消息。

The way I implemented is the following: 我的实现方式如下:

startComponent: startComponent:

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

And the template: 和模板:

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

Note: I'm using x-templates since it somehow makes the most sense with the rest of the application being Python/Flask. 注意:我使用的是x-templates,因为它在某种程度上使Python / Flask应用程序的其余部分最有意义。 But everything is wrapped in {% raw %} so the brackets are not the issue. 但是,所有内容都包装在{% raw %}因此括号不是问题。

Quiz Component: 测验部分:

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

And the template: 和模板:

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

And as you might have seen I'm using a QuizStore that stores all the states. 如您所见,我正在使用QuizStore存储所有状态。

The store: 商店:

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

In the main .html I'm implementing the dynamic component as follows: 在主要的.html文件中,我正在实现动态组件,如下所示:

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

So what works: 那么有效的方法是:

  • The Start screen with the button shows up. 出现带有按钮的“开始”屏幕。
  • When I click on the Start Button, the quizComponent shows up as expected. 当我单击“开始”按钮时,quizComponent会按预期显示。

What does not work: 什么不起作用:

  • The {{ self.question }} data in the QuizComponent template does not show up. QuizComponent模板中的{{ self.question }}数据未显示。 And it does not throw an error message. 并且它不会引发错误消息。
  • it also does not work with {{ question }}. 它也不适用于{{问题}}。

What I don't understand: 我不明白的是:

  • If I first render the quizComponent with setting QuizStore.currentComponent = 'startComponent' , the data shows up neatly. 如果我首先通过设置QuizStore.currentComponent = 'startComponent'渲染quizComponent,那么数据将整齐显示。
  • If I switch back to <quiz-component></quiz-component> (rather than the dynamic components), it works as well. 如果我切换回<quiz-component></quiz-component> (而不是动态组件),它也可以正常工作。
  • So it seems to be the issue that this. 因此,这似乎是一个问题this. does not refer to currently active dynamic component - so I guess here is the mistake? 不涉及当前活动的动态组件-所以我想这是错误的吗? But then again I don't understand why there is no error message... 但是话又说回来,我不明白为什么没有错误信息...

I can't figure out what the issue is here - anyone? 我不知道这里是什么问题-有人吗?

You may have some issues with your parent component not knowing about its child components, and your construct for QuizStore has a data layer that you don't account for when you set currentComponent . 您的父组件可能不知道其子组件会遇到一些问题,并且QuizStore的构造具有一个data层,您在设置currentComponent时无需考虑这一data层。

 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 } }); 
 <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> 

The following worked in the end: 最终,以下工作:

I just wrapped <component :is="QuizStore.currentComponent"></component> in a parent component ("index-component") instead of putting it directly in the main html file: 我只是将<component :is="QuizStore.currentComponent"></component>包装在父组件(“ index-component”)中,而不是直接将其放置在主html文件中:

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

And within the index-component: 在index-component内:

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

Maybe this would have been the right way all along, or maybe not, but it works now :) Thanks a lot Roy for your help! 也许这一直是正确的方法,也许不是,但是现在可以了:)非常感谢Roy的帮助!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM