在vue.js函数执行期间显示加载动画

3

一个在加载元素上简单的显示和隐藏在Vue js函数执行期间失败了。

我有一个Vue js函数,它将在完成后执行某些事情并更新数据。我试图在此过程中显示加载动画。出于讨论目的,我已经将此过程简化为一个简单的循环,以消除所有其他问题(例如ajax、async等)。

我的按钮HTML如下所示:

<button type="button" v-on:click="DoStuff()">Do Stuff</button>

我的Vue.js代码如下所示:
var client = new Vue({
    el: '#client',
    data: {
        someData: []
},
methods: {
    DoStuff: function() {

        //Show Loader
        $(".loader").show();

        //Waste 5 seconds
        for (var i = 0; i < 100000000; i++) {
            var x = i;
        }

        //Hide loader
        $(".loader").hide();

        // let me know it's done.
        alert('cool');
    }

加载器从未出现。如果我注释掉hide命令,加载器会在警报后显示。这让我想到某种异步操作正在进行,但我没有执行异步操作。

1
有些东西可以帮助解释当前的问题:只有当函数执行完成后,DOM 才会被渲染出来。您可以在这里阅读更多信息:https://dev59.com/pIrda4cB1Zd3GeqPQcHA - Andrew Lohr
4个回答

8

您不需要使用jQuery根据条件设置和隐藏页面元素,事实上,这种做法有点违背VueJS和其他前端JavaScript框架的用途。

首先,您应该在data对象中添加一个名为loading的属性。

data: {
   someData: [],
   loading: false
}

然后,在您的doStuff函数中,删除jquery行并相应地设置loading属性。

methods: {
    doStuff: function() {
        //Show Loader
        this.loading = true;

        //Waste 5 seconds
        setTimeout(() => {
           this.loading = false;
        }, 5000)
    }
}


最后,在您的视图中添加此行代码。
<div v-if="loading">Loading some data</div>

我想说的是,我认为你的代码片段有些混乱。 methods 属性应该在 Vue 实例定义内部。
var client = new Vue({
    el: '#client',
    data: {
        someData: [],
        loading: false
    },
    methods: {
       doStuff: function() {
          //Show Loader
          this.loading = true;

          //Waste 5 seconds
          setTimeout(() => {
            this.loading = false;
          }, 5000)
       }

   }
}


谢谢。请看我对perellorodrigo的回复。这种方法在许多表格和页面上不可扩展。 - ArdAtak
@ArdAtak 你仍然不应该使用jquery。这是正确的方法,你只需要在父组件中定义loading并向子组件传递即可。另外,我认为你对“可扩展”这个词的理解有误。 - Isaac Vidrine

2

不要使用jquery。你可以使用vuejs来完成此操作。


var client = new Vue({
    el: '#client',
    data: {
        someData: [],
        loading: false,
},
methods: {
    DoStuff() {

        //Show Loader
        this.loading = true;

        //Waste 5 seconds

        //Hide loader
        this.loading = true;

        // let me know it's done.
        alert('cool');
    }


最初的回答
以及你的HTML。
<div class="loading" v-if="loading">
    Loading....
</div>
<div v-else>
The rest of your website 
</div>


0
最好不要与JQuery混合使用,而是使用Vue的条件显示(v-show)。
在你的加载器中:
<div class="loader" v-show="loading"></div>

在你的Vue代码中:
var client = new Vue({
    el: '#client',
    data: {
        someData: [],
        loading: false
},
methods: {
    DoStuff: function() {

        this.loading = true;

        //Waste 5 seconds
        for (var i = 0; i < 100000000; i++) {
            var x = i;
        }

        this.loading = false;

        // let me know it's done.
        alert('cool');
    }

谢谢。问题是我试图在父页面上使用一个全局加载动画,并从进行ajax调用的全局命令中操作它。因此,我不想在每个表单和每个函数中都添加单独的加载动画和加载元素。我试图简化问题以显示每当点击vue js按钮并执行函数时,最基本的Show / Hide都会失败。尽管如我所提到的,如果我注释掉Hide命令,那么在警报之后加载程序确实会显示出来。 - ArdAtak
好的,如果是这样的话,你应该使用事件总线。通过使用事件,您不会受到子父关系的限制。因此,每当您发出任何请求时,在任何子级中触发事件并在父级中捕获它。请阅读本文,您可能更感兴趣的是最后一部分:https://flaviocopes.com/vue-components-communication/ - perellorodrigo

-3

谢谢大家。我必须专注于一个更重要的功能,但我只是想分享一下我所了解到的内容。这不是最终答案,但它解释了问题和正确的方法。

问题由Andrew Lohr正确识别,并在此进一步解释: jQuery hide()和show()在函数后期反转时不会立即运行

最好(但不是唯一)的解决方案是使用事件总线,正如perellorodrigo在这里提到的那样:https://flaviocopes.com/vue-components-communication/

当我有时间时,我会发布我的最终解决方案。


正确的做法是不要在Vue中使用jQuery。 - Michael Mano

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接