Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

I made a small library to track the loading of all my api calls.(我做了一个小库来跟踪所有api调用的加载。)


It basically is an array which contains objects describing one loading process.(它基本上是一个数组,其中包含描述一个加载过程的对象。) I import this library into a Single File Component to make calls to it.(我将此库导入单个文件组件以对其进行调用。) I then pass the array from the library to a child component and want to render all my objects in the array (the loading statuses).(然后,我将数组从库传递到子组件,并希望呈现数组中的所有对象(加载状态)。) I see the data updating in Vue Devtools on the child component, however it is not updated in the page.(我在子组件上的Vue Devtools中看到了数据更新,但是页面中没有更新。)

What i tried:(我试过的)

  • passing the vue instance from the parent component and use $set to update the array(从父组件传递vue实例,并使用$ set更新数组)
  • using array.splice to update the array(使用array.splice更新数组)
  • creating a new object with Object.assign, update the new object and then update the array (splice/$set)(使用Object.assign创建一个新对象,更新新对象,然后更新数组(splice / $ set))
  • passing a key and updating this key when updating thew object(在更新thew对象时传递密钥并更新此密钥)
  • calling methods in the library in the console(在控制台的库中调用方法)

sample updating function:(样品更新功能:)

function _finish(name, descFinished) {
        const i = _loaders.findIndex(l => l.name == name);
        if(i < 0) throw new NameNotFoundException(name);
        let loader = Object.assign({}, _loaders[i]);
        if(descFinished != undefined) loader.descFinished = descFinished;
        loader.loading = false;
        loader.error = false;
        loader.endTime = new Date();
        vm.$set(_loaders, i, loader);
        return _loaders[i];
}

I pass to the child component like this(我像这样传递给子组件)

<loading-status v-if="loadstatus" :statuses="loadstatus.getAllLoaders()"></loading-status>

child component looks this this(子组件看起来像这样)

<template>
    <div v-if="statuses">
        <div v-for="status in statuses" :key="status.name">
            <div>
                {{ status.loading == true ? 'true' : 'false' }}
            </div>
        </div>
    </div>
</template>

<script>
export default {
    name: 'loading-status',
    props: {
        statuses: {
            type: Array,
            required: true
        }
    }
}

image of the array not being reactive on the page(阵列的图片在页面上没有反应)

some more information that may be useful:(一些可能有用的更多信息:)

the library structure:(库结构:)

function loadmanager(vueinstance) {
    //library internals here
    // for example my array i want to render:
    let _loaders = [];
    var publicInterface() {
        //public accesable functions here
        //i call this to pass the array to my child component
        getAllLoaders() {
            return _loaders;
        }
    }
    return publicInterface;
}
exports.makeLoadManager = loadmanager;

i import the library in the vue SFC and call it in the mounted hook(我将库导入Vue SFC中,并在安装的挂钩中调用它)

import loadhelper from "../../helpers/Loadstatus.js";
...
data() {
    return {
        loadstatus: null
    }
}
...
mounted() {
    this.loadstatus = loadhelper.makeLoadManager(this);
}

My question boils down to: How do I reactively render or correctly update an array from a js library in vue.(我的问题归结为:如何在vue中从js库中反应性渲染或正确更新数组。)

I would be happy to provide more information if that helps answering my question.(如果能帮助回答我的问题,我很乐意提供更多信息。)

  ask by lcberg translate from so

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
532 views
Welcome To Ask or Share your Answers For Others

1 Answer

If your library is creating (and managing) an array of "loaders", simplest thing you can do is define empty reactive array in your Vue component's data and in mounted hook assign a reference to your's library array into it.(如果您的库正在创建(和管理)“加载程序”数组,那么您可以做的最简单的事情是在Vue组件的数据中定义空的反应性数组,并在mounted挂钩中向其中分配对您的库数组的引用。)

Like this:(像这样:)
import LoadingStatus from "./components/LoadingStatus";
import loadhelper from "./helpers/LoadManager.js";

export default {
  name: "App",
  components: {
    LoadingStatus
  },
  data() {
    return {
      statuses: []
    };
  }
  mounted() {
    this.statuses = loadhelper.getAllLoaders();
  }
};

Vue takes the array provided by your library and makes it reactive.(Vue接受您的库提供的数组,并使它具有反应性。)

You can use template like this:(您可以使用如下模板:)
<LoadingStatus :statuses="statuses"/>

See the demo(观看演示)

As long as both Vue and your "load manager" are working with the same array (reference), its all good.(只要Vue和您的“负载管理器”都在同一个数组(引用)上工作,一切都很好。)

I'v added setTimeout callback into LoadManager to demonstrate that changes "from the outside of Vue" to the array will make Vue component re-render....(我在LoadManager添加了setTimeout回调,以演示“从Vue外部”对数组的更改将使Vue组件重新呈现。)

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...