vuejs3progress-barprogress

In vue3, the value of progress in fake-progress is not updated in the view, it is always 0


in vue3,I want to add a progress bar for network requests,so i use fake-progress,but i can use it, because its value is not responsive there is my code :

<template>
    <div>
        {{ progress }}
        <!-- <el-progress type="circle" :percentage="parseInt(progress * 100)"></el-progress> -->
    </div>
</template>

<script setup>
import FakeProgress from 'fake-progress';
import { reactive, toRef, watch, watchEffect } from 'vue';

let fake = new FakeProgress({
    timeConstant: 1000,
    autoStart: true,
})

let fakeRef = reactive(fake)
let progress = toRef(fakeRef, 'progress')

setInterval(() => {
    console.log(fake.progress);
    console.log(fakeRef.progress);
    console.log(progress);
}, 1);

</script>

all of the value is changed, but in the view {{progress}} is always 0 how can i do it? why is this,wuwuwu

I want the numbers on the page to be changing


Solution

  • The FakeProgress isn't a vue reactive. So we need to add some reactivity here...

    A simple solution would be to override the progress property and update your progress ref on changes:

    The live gist is here.

    <script setup>
    import FakeProgress from 'fake-progress';
    import { ref } from 'vue';
    
    const fake = new FakeProgress({
        timeConstant: 1000,
        autoStart: true,
    });
    
    const progress = ref(0);
    
    Object.defineProperty(fake, 'progress', {
      set(val){
        progress.value = val;
      },
      get(){
        return progress.value;
      }
    });
    
    </script>
    
    <template>
        <div>
            {{ progress }}
        </div>
    </template>
    

    A more clever solution would be to provide a reactive object as this to construct a FakeProgress's instance:

    The live gist is here.

    <script setup>
    import {FakeProgress} from './fake-progress.js';
    import { reactive } from 'vue';
    
    // create our custom reactive instance
    const fake = reactive({});
    
    // set prototype
    Object.setPrototypeOf(fake, FakeProgress.prototype);
    
    // call constructor
    FakeProgress.bind(fake)({
        timeConstant: 1000,
        autoStart: true,
    });
    
    </script>
    
    <template>
        <div>
            {{ fake.progress }}
        </div>
    </template>