【问题标题】:Vue.js Dynamic Component - Template not showing components dataVue.js 动态组件 - 模板不显示组件数据
【发布时间】:2017-12-25 19:23:55
【问题描述】:

我正在尝试使用 VueJs 构建一个问答游戏,到目前为止一切都很顺利,但是现在我开始使用 动态组件 我遇到了显示数据。

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

我的实现方式如下:

开始组件:

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,则数据会整齐地显示出来。
  • 如果我切换回&lt;quiz-component&gt;&lt;/quiz-component&gt;(而不是动态组件),它也能正常工作。
  • 所以this. 似乎不是指当前活动的动态组件的问题 - 所以我想这是错误的吗?但是话又说回来,我不明白为什么没有错误消息...

我无法弄清楚这里的问题 - 任何人?

【问题讨论】:

  • 这似乎不是动态组件问题,因为当我用&lt;start-component v-if="QuizStore.currentComponent === 'start-component'"&gt;&lt;/start-component&gt;&lt;quiz-component v-if="QuizStore.currentComponent === 'quiz-component'"&gt;&lt;/quiz-component&gt; 替换它时,我遇到了同样的问题..

标签: vue.js


【解决方案1】:

您可能会遇到一些问题,即您的父组件不知道其子组件,并且您的 QuizStore 构造有一个 data 层,当您设置 currentComponent 时您没有考虑到该层。

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>

【讨论】:

  • 感谢您的快速答复! sn-p 工作正常 - 我的代码看起来一样。但不知何故它仍然不起作用。您能否详细说明“您的 QuizStore 构造有一个您在设置 currentComponent 时不考虑的数据层”是什么意思?
  • 在你的问题中,你有:is="QuizStore.currentComponent",但它应该是:is="QuizStore.data.currentComponent"
  • 感谢您的回答。这不是问题,因为我在我的 Vue() 应用程序中定义了data { QuizStore.data }(很抱歉没有发布),所以动态组件的过渡效果很好。但是第二个组件的数据没有显示......仍然不知道我错过了什么......
  • 我最好的猜测是quiz-component 没有在应用程序级别定义。检查调试器中的 HTML 以查看是否正在实例化任何内容。您也可以在模板中放一些样板文本,看看是模板还是模板中的变量没有显示出来。
  • 再次感谢。模板渲染得很好,如果我输入样板文本,甚至从该模板中的商店访问数据,它就可以正常工作。但不是来自同一组件的数据。关于应用程序级别:我像在 Vue 应用程序中那样定义它,现在我切换到使所有组件成为全局 Vue.component('start-component', {... 仍然是同样的问题。用 Vuex.store 实现了 Vuex,但仍然是同样的问题,数据没有显示出来……我一定在某处犯了一个根本性错误.. :/
【解决方案2】:

以下工作最终奏效:

我只是将&lt;component :is="QuizStore.currentComponent"&gt;&lt;/component&gt; 包裹在一个父组件(“index-component”)中,而不是直接放在主 html 文件中:

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

在索引组件内:

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

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

【讨论】:

    猜你喜欢
    • 2019-08-06
    • 2018-10-27
    • 2020-05-14
    • 1970-01-01
    • 2021-07-17
    • 2017-03-31
    • 2020-02-13
    • 2019-04-05
    • 2021-07-13
    相关资源
    最近更新 更多