我在问自己,我们目前的实现是否是"最佳"方式,或者是否有任何其他方法会更好。
给定一个搜索组件,该组件在下拉列表中显示其结果。我们需要这个组件来做许多用例,比如搜索位置或人员。因此,我们需要执行不同的 API 请求。
我们目前的方法是使用具有"抽象"方法的AbstractSearchInput.vue
组件executeSearch()
该方法在我们的具体组件LocationSearchInput.vue
或PersonSearchInput.vue
中被覆盖。
<template>
<input @input="performSearch"/>
</template>
<script>
export default {
name: "AbstractSearchInput",
data() {
return {
query: "",
result: null,
};
},
methods: {
async executeSearch(query) {
// concrete components extending this abstract component need to implement this method
throw new Error("No implementation");
},
async performSearch() {
this.result = await this.executeSearch(query);
},
// more stuff
},
};
</script>
<script>
import { queryPersons } from "../personsApi";
export default {
name: "PersonsSearchInput",
extends: AbstractSearchInput,
methods: {
async executeSearch(query) {
const persons = await queryPersons(query);
return persons;
},
},
};
</script>
人Api.js
async function queryPersons() {
const response = await fetch(url); // shortened
if (!response.ok) {
throw new Error("Foo");
return response.json();
}
这种继承方法正在发挥作用。但是,它的缺点是我们需要为每个新用例提供一个具体的组件。想象一下,我们需要搜索水果、徽标或其他东西......
一开始,我认为会有一种方法可以使这个组件可配置。我想象只有一个搜索组件,您可以在外部配置搜索内容。就像通过 prop 将 API 请求传递给组件一样。但是,将函数作为道具传递是一种反模式。是否有任何其他注意事项可能会产生较少的样板代码?
到目前为止谢谢:slight_smile:
定义一个名为useSearch
的可组合函数,它将url
作为参数并返回result
:
import {ref} from 'vue'
export default function useSearch(cb){
const result=ref([]);
async function performSearch() {
result.value = await cb();
}
return { performSearch, result }
}
在组件中:
<script>
import {ref} from 'vue'
import useSearch from './useSearch'
import { queryPersons } from "../personsApi";
export default {
name: "PersonsSearchInput",
setup(){
const { performSearch, result:persons }= useSearch(queryPersons)
return { performSearch, persons }
}
};
</script>