代码之家  ›  专栏  ›  技术社区  ›  Collin Allen

如何反应性地公开第三方图书馆的内容?

  •  0
  • Collin Allen  · 技术社区  · 3 年前

    在Vue 3下,当包装一个维护自己内部状态的第三方库时,如果它只通过函数调用公开该状态,我如何反应性地观察该状态?

    我试过使用 computed() 在下面的例子中,但计算的函数只执行一次(可能是为了初始渲染),然后再也不会执行了。

    <template>
      <ul>
        <li v-for="thing in things" :key="thing.id">{{ thing.name }}</li>
      </ul>
    </template>
    
    <script>
    import { computed } from 'vue';
    import ExampleLibrary from '@somethirdparty/example-library';
    
    export default {
      setup() {
        const instance = ExampleLibrary();
    
        const things = computed(() => {
          // This computed function fires once, and never again.
          // How can I reactively expose the result of `instance.getThings()`?
          return instance.getThings();
        });
    
        return {
          things
        };
      }
    };
    </script>
    

    所有Vue 3 reactive() computed() 我能找到的例子是一些琐碎的例子,它们假设状态(或它的一些导数)可以作为局部变量直接使用,而不是通过我不维护其内容的第三方库。

    (如果重要的话,我正在与之交互的特定库是 Uppy ,而我想观察的结果是 getFiles 。不过,我试着让这个问题变得通用,因为它似乎适用于许多情况。)

    0 回复  |  直到 3 年前
        1
  •  1
  •   Moritz Ringler    3 年前

    除非库公开其内部状态(不应该公开),否则不能使数据本身成为被动的。我认为 getFiles() 每次返回一个新数组,而不是内部引用,所以类似 reactive(uppy.getFiles()) 不会起作用。

    一般的方法是像连接Vue组件一样连接库,只是在使用props将数据传递给组件的情况下,将API函数与库一起使用,并使用库的事件来检索更新。

    使用Uppy中的文件数组,可以使用 addFile() removeFile() 方法将数据传递给Uppy并使用事件 files-added file-removed 以检索更新。

    以下是最小设置:

    const uppy = new Uppy().use(...)
    const files = ref([])
    uppyInstance.on('files-added', (addedFiles) => files.value.push(...addedFiles))
    uppyInstance.on('file-removed', (removedFile) => files.value = files.value.filter(file => file !== removedFile))
    // or just
    uppyInstance.on('files-added', () => files.value = uppy.getFiles())
    uppyInstance.on('file-removed', () => files.value = uppy.getFiles())
    

    现在 files 将始终与Uppy实例保持同步。您可以将其封装到Vue组件中(如果不需要模板代码,则可以组合)。看看 playground

    如果你想写一个完整的包装器,你可以使用同样的原理来公开Uppy中的其他事件并将数据传递给它。最后,你可以写这样的东西:

    <uppy-drag-n-drop
      v-model="files"
      :note="Upload File"
      @onDragOver="..."
    />
    
    推荐文章