先定义一个默认接口实现 defaultSearcher.js
// 默认接口实现 defaultSearcher.js
class DefaultSearcher {
searchByKeyword () {
return fetch(api.user.queryDefaultUser, {}) // 默认实现
}
static get singleton () {
const ThisUserSelect = this
return Object.prototype.hasOwnProperty.call(ThisUserSelect, '_singleton_')
? ThisUserSelect._singleton_
: (
ThisUserSelect._singleton_ = new ThisUserSelect()
)
}
}
export {
DefaultSearcher
}
定义一个基础组件 UserSelect
// 基础组件 UserSelect
import { DefaultSearcher } from './defaultSearcher'
export default {
props: {
searcher: {
type: Object,
default: () => DefaultSearcher.singleton
},
},
methods: {
fetchUserList () {
this.searcher.searchByKeyword()
}
}
}
直接调用这个基础组件
<template>
<UserSelect></UserSelect>
</template>
这里定义一个基础组件UserSelect只负责自己业务不涉及接口调用,所有的接口调用由DefaultSearcher这个默认实现类以及他的子类来提供数据来源包括对数据的处理,如果没有传searcher就会调用默认的实现,其他组件也可以有自己的实现,举个栗子:
定义一个自定义的接口实现 customSearcher.js
// customSearcher.js
import { DefaultSearcher } from './defaultSearcher'
class CustomSearcher extends DefaultSearcher {
searchByKeyword () {
return fetch(api.user.queryCustomUser, {}) // 自定义接口
}
}
export {
CustomSearcher
}
调用这个基础组件并传入自定义的接口实现
<template>
<UserSelect :searcher="customSearcher"></UserSelect>
</template>
<script>
import { CustomSearcher } from './customSearcher'
export default {
computed: {
customSearcher () {
return CustomSearcher.singleton
}
}
}
</script>
以上策略模式在进行组件封装上会提供很大的帮助,并且无论接口怎么变化扩展起来都会很方便。