admin管理员组文章数量:1389805
I'm starting to get comfortable with Vue's composition API, but every time I make a composable I ask myself which pattern to use. If I have a composable whose state depends on outside triggers:
- should I return a function from the composable that performs an action on the state? Or
- should I instead let the composable accept a reactive state from outside to update the state managed by the composable?
Scenario: list users
For example, I need to make a composable that fetches a list of users from an API. The list must reactively update when filtered by user name.
Composable pattern 1: return reactive list and action on that list
<script setup lang="ts">
const { list, setList } = useUserList();
</script>
<template>
<pre>{{ list }}</pre>
<button type="button" @click="setList('john')">List users named "John"</button>
</template>
Composable pattern 2: return reactive list based on input reactive dependency
<script setup lang="ts">
const nameFilter = ref('');
const { list } = useUserList(nameFilter);
</script>
<template>
<pre>{{ list }}</pre>
<button type="button" @click="nameFilter = 'John'">List users named "John"</button>
</template>
Which of the two patterns should I do? The example scenario may be simple enough to make the choice negligible, but on more complex logic (e.g., making higher-order composables) I imagine its effect compounding.
I'm starting to get comfortable with Vue's composition API, but every time I make a composable I ask myself which pattern to use. If I have a composable whose state depends on outside triggers:
- should I return a function from the composable that performs an action on the state? Or
- should I instead let the composable accept a reactive state from outside to update the state managed by the composable?
Scenario: list users
For example, I need to make a composable that fetches a list of users from an API. The list must reactively update when filtered by user name.
Composable pattern 1: return reactive list and action on that list
<script setup lang="ts">
const { list, setList } = useUserList();
</script>
<template>
<pre>{{ list }}</pre>
<button type="button" @click="setList('john')">List users named "John"</button>
</template>
Composable pattern 2: return reactive list based on input reactive dependency
<script setup lang="ts">
const nameFilter = ref('');
const { list } = useUserList(nameFilter);
</script>
<template>
<pre>{{ list }}</pre>
<button type="button" @click="nameFilter = 'John'">List users named "John"</button>
</template>
Which of the two patterns should I do? The example scenario may be simple enough to make the choice negligible, but on more complex logic (e.g., making higher-order composables) I imagine its effect compounding.
Share Improve this question edited Mar 13 at 8:47 Christian asked Mar 13 at 8:38 ChristianChristian 8311 gold badge6 silver badges19 bronze badges 2 |1 Answer
Reset to default 0Setter function is generally redundant in Vue because refs are reactive and can be watched. As a rule of thumb, modified pattern 1 is commonly used:
const { list, filter } = useUserList();
If a composable is implemented for team or public usage, then both modified pattern 1 and pattern 2 are applicable. It may be necessary to pass a ref that already exists to a composable.
A universal implementation that allows both uses:
function useUserList(filter = ref()) {
const list = ref();
...
return { list: readonly(list), filter }
}
版权声明:本文标题:vue.js - Exposing actions in composable vs accepting reactive state to update internal state? - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1744713374a2621259.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
nameFilter
becomes extensive, using Composable Pattern 1 would lead to overly bloated code, in which case I would opt for Composable Pattern 2 or other patterns. – yuanyxh Commented Mar 13 at 8:57nameFilter
ref in pattern 1 then callsetList(nameFilter.value)
every time the ref value changes. – Christian Commented Mar 13 at 9:45