如何在特定事件(例如@click @change)后渲染/创建Vue组件

时间:2018-08-07 11:05:35

标签: javascript jquery vuejs2 vue-component

我是Vue JS的新手,现在面对一个问题,这似乎很简单,但我找不到解决方法。

这就是我想要做的原因: -我想先从服务器/本地加载一些数据,编辑数据,然后将数据显示给用户。但是要加载的数据由用户决定(通过按钮,例如click事件)

  • 因为显示数据的方式有点太复杂了(我的意思是HTML代码,UI),所以我决定创建一个全局组件来处理它,因此不会弄乱我的Vue实例。

我几乎已经做了部分组件,但是问题是,每次刷新页面时,都会出现警告,提示某些参数未定义。

当然,它们不是在一开始就定义的,因为用户尚未选择要加载的数据。

有经验的人可以告诉我。我该如何告诉Vue在单击事件之后渲染组件?

我将在下面尝试制作一个简化的代码示例,以便您更好地理解:

-main.js文件的一部分(简体)

// the global Vue component
var infoBox = Vue.component('info-box', {
    props:['infos'],
    template:`
        <div>
            <li>{{ infos.name }}</li>
            <li>{{ infos.id }}</li>
            <li>{{ infos.title }}</li>
            <li>{{ infos.whatever }}</li> // continues..also simplified, actually I need to edit the infos first
        </div>
    `
}

// the Vue instance
var app = new Vue ({
    el: '#app',
    data: {
        data: '',
    },
    methods: {
        loadData: function() {
            // load the needed data from the server
            this.data = $.getJSON(/*....*/) // just for example that I loaded some data and push it to the instance


        }
    }
})

-HTML文件的一部分

<div id="app">
    <button @click="loadData"></button> // also simplified, the real project has different kinds of buttons, the user can decide which data should be loaded
    <info-box :infos="data"></info-box> // get the data from the Vue instance, which does not exist until the button was clicked the the data was loaded
</div>

有关我的问题的更多详细信息: -工作流程实际上还可以,因为我已经在Vue实例中定义了一个空的“数据”。真正的问题是在组件内部,当我要编辑和处理一些数据时,因为在单击之前,数据为空,所以我收到很多“未定义XXX”的警告,因为我使用的某些功能没有允许未定义的道具。

  • 我想要的完美方法:我可以对Vue说些什么:OK,现在单击按钮,让我们看看,数据已加载,现在请渲染/创建组件。

  • 如果没有,那么唯一的办法就是在创建Vue实例时首先加载所有数据。但是显然这是太多的数据,并且会引起问题。

  • 我试图了解Vue官方文档“异步组件”,这似乎是我的最佳解决方案:

  

https://vuejs.org/v2/guide/components-dynamic-async.html

但是我不能再走了,因为我根本不理解这一点,也无法在我的项目中使用它( ,我认为这段代码是告诉Vue的关键,他现在可以渲染/创建组件 ):

require(['./my-async-component'], resolve)
  • 此外, setTimeOut 并不是我想要的,因为如果用户不单击按钮,我们可以等到世界结束时,数据始终为空。

1 个答案:

答案 0 :(得分:0)

有数十种方法可以解决此问题。

您只需在组件上设置v-if="data",仅在加载数据时才加载整个组件。通常,我会使用v-else在其下放置另一个元素,并具有一个加载微调器组件或类似的东西。

如果要获得组件的布局,可以在info-box组件的模板中进行相同的操作。

<div>
    <div class="wrapper" v-if="infos">
        <li>{{ infos.name }}</li>
        <li>{{ infos.id }}</li>
        <li>{{ infos.title }}</li>
        <li>{{ infos.whatever }}</li>
    </div>

    <div class="spinner-loading">
        Put your loading animation here
    </div>
</div>

异步组件将无济于事,因为异步组件可能实际上在AJAX请求实际完成之前就已加载。您误解了异步组件的工作原理。

您还可以为每个信息属性创建计算属性,如果未设置占位符,则放置占位符,以便您可以单独管理它们。这里有很多选项,但是在显示模板之前,您需要确保拥有数据或至少一个占位符。