Vuejs3/Vuex4 承诺履行时有条件渲染

Vuejs3/Vuex4 conditional render on promise fulfillment

我有自定义的 object 用于保存 child object 的全部数据。 child object 的所有属性均以空值启动,因此可以引用 object 并从远程源填充它们的属性。这将创建一个 lazy-loading 设置。

此代码将极度精简,但所有相关内容都应在此处:

class Collection extends Object {
    constructor(){
        this.loaded = false;
        var allLoaders = [];
        var loaderPropmises = [];
        var resolver;
        const $this = this;
        var trackLoaders = function(){
            $this.loaded = false;
            loaderPromises.push(Promise.all(allLoaders).then(() => {
                //... irrelevant logic in here to ensure only the latest promise sets loaded to true
                $this.loaded = true; //This is getting called where I expect
                resolver(); 
            }));
        }
        
        //hook for outside things to watch the promise if they want
        this.loader = new Promise((resolve) => {
            //this only gets resolved once, which is fine
            resolver = resolve;
        });


        //... bunch of code around adding child objects, but the important part:
        this.add(child){
            this[child.id] = child;
            this.allLoaders.push(child.loader); 
            trackLoaders();
        }
    }
}

然后 child 看起来像:

class Child extends Object {
     constructor(){
         this.loaded = false;
         var resolver;
         const $this = this;
         this.loader = new Promise((resolve) => {
             resolver = resolve;
         }).then((){
             $this.loaded = true;
         });

         this.populate(data){
             //bunch of stuff to set data to properties on this object
             resolver();
         }
     }
}

在 Vuex 4 中,我将这些集合作为商店中“AppData”object 的属性:

const store = createStore({
    state: function(){
        AppData: {}
    },
    mutations: {
        setupCollection(state, name){
            if (!Object.hasOwnProperty.call(state.AppData, name){
                state.AppData[name] = new Collection();
            }
        }
    },
    actions: {
        //this is called on each row of data returned from an Axios call
        add (context, {name, data}){
            context.state.AppData[name][data.id].populate(data);
        }
    }
});

想法是,每当将 Child 添加到 Collection 时,集合 loaded 属性 将为假,直到所有 Child 加载器承诺解决。这一切都完美执行......除了 loaded 布尔不是反应性的。

现在,我在每个组件的 Created 函数中都有一个 Promise.all,一旦组件所需的所有 objects 都已解决其“加载器”承诺,它就会将该组件标记为“已加载” .这绝对有效,但并不理想,因为不同的数据将在不同的时间可用,有时屏幕上会同时显示数百个或更多 类。我想要完成的是:

<div v-if="!myCollection.loaded">
    Loading...
</div>
<div v-else>
    Show the data I want here {{myCollection.property}}
</div>

所以我有两个想法来克服这个问题,任何一个都很好:

看起来 Vue's ref 是我需要的:

this.loaded = ref(false);

这有效,至少在 Child class 上有效。我遇到了某种循环引用问题,无法在 Collection class 上进行测试,是的,但它应该可以正常工作。