Vue可组合-如何在不共享状态的情况下使用可组合的多个示例?

lmyy7pcs  于 2023-03-03  发布在  Vue.js
关注(0)|答案(1)|浏览(160)

我的VueJS应用程序中有一个可组合文件:

// simple example of a composable that fetch some information from API and shows that information 
// in a table in two components at the sime time
export function useDatatable () {
  const table = ref({
    headers: [...],
    items: [],
    someValue: ''
  })

  async function getDocuments () {
    const { data } = await $axios.get('/documents')
    table.value.items = data
  }

  return {
    table,
    getDocuments
  }
}

然后我有多个组件同时使用这个可组合组件:

<template>
  <div>
    <document-table /> // composable is used here
    <document-billing-dialog /> // composable is used here too
  </div>
</template>

然后在两个组件(document-tabledocument-billing-dialog)中,我像这样使用这个组合:

<template>
  <div>
    {{ table.someValue }}
  </div>
  <v-table :items="table.items" />
  <v-btn @click="getDocuments">
    Reload table
  </v-btn>
  // other components
</template>

<script>
  import { useDatatable } from '~/composables/useDatatable'
  // other imports

  export default defineComponent({
    setup () {
      const { table, getDocuments } = useDatatable()

      onMounted(() => { getDocuments() })

      return {
        table,
        getDocuments
      }
    }
  })
</script>

但是,当一个组件调用getDocuments函数时,它会被调用两次,因为它同时在两个组件中使用。
另一个例子是,如果我更改table.value.someValue = 'something'的值,则两个组件都会更改。
是否有办法同时拥有可组合对象的多个示例而不共享状态?

pw9qyyiw

pw9qyyiw1#

偶然发现了同样的问题。我的解决方案是,将可组合函数

// simple example of a composable that fetch some information
// from API and shows that information 
// in a table in two components at the sime time

let tables = reactive([])

export default function useDatatable(datatableName) {
  tables[datatableName] = datatable()
  return tables[datatableName]
}

function datatable {
  const table = ref({
    headers: [...],
    items: [],
    someValue: ''
  })

  async function getDocuments() {
    const {
      data
    } = await $axios.get('/documents')
    table.value.items = data
  }

  return {
    table,
    getDocuments
  }
}

使用名称启动可组合对象

<script>
  import useDatatable from '~/composables/useDatatable'
  // other imports

  export default defineComponent({
    setup () {
      const { table, getDocuments } = useDatatable('table-1')
    ...

相关问题