Vue中如何抽取部分代码到单独的ts文件
本文代码基于
简单示例
这段代码,是比较通用的代码,我想抽取成一个ts文件,来供其他地方调用。
const groupData = reactive({
groupList:[] as Array<GroupV2Response>,
current:{} as GroupV2Response,
})
const groupFunc = new class {
groupType = 1;
loadGroupChildrenList = (parentGroupCode:string|null) => {
axios.post("/gallery/group/query-group-children",{
groupCode:parentGroupCode,
type:this.groupType,
}).then(resp => groupData.groupList = resp.data.data)
}
selectThisGroup = (group:GroupV2Response) => {
groupData.current = group;
this.loadGroupChildrenList(group.groupCode);
}
clearCurrentGroup = () => {
groupData.current = {} as GroupV2Response;
}
}
为了将这段代码抽取成一个 TypeScript 文件供其他地方调用,并且能够操作 Vue 的响应式变量,可以考虑以下几个步骤:
- 创建一个 TypeScript 文件:这个文件将包含类和响应式数据结构。
- 抽象出响应式状态:可以将响应式状态 (
reactive
对象) 作为参数传递给类,使得这个类更加灵活和可重用。 - 导出类和响应式状态:从这个文件中导出你创建的类和函数,这样其他组件或文件就可以引用和实例化它。
步骤 1: 创建 TypeScript 文件
首先,创建一个新的 TypeScript 文件,例如命名为 GroupManager.ts
。
步骤 2: 抽象出响应式状态
你可以修改类,让它接收一个响应式状态对象作为参数。这样,类就不依赖于外部的具体响应式变量了。
// GroupManager.ts
import { reactive } from 'vue';
import axios from 'axios';
import { GroupV2Response } from './path-to-type-definitions'; // 确保引入了正确的类型定义
// 定义响应式状态接口
interface GroupData {
groupList: Array<GroupV2Response>;
current: GroupV2Response;
}
export class GroupManager {
private groupData: GroupData;
groupType = 1;
constructor(groupData: GroupData) {
this.groupData = groupData;
}
loadGroupChildrenList = (parentGroupCode: string|null) => {
axios.post("/gallery/group/query-group-children", {
groupCode: parentGroupCode,
type: this.groupType,
}).then(resp => this.groupData.groupList = resp.data.data);
}
selectThisGroup = (group: GroupV2Response) => {
this.groupData.current = group;
this.loadGroupChildrenList(group.groupCode);
}
clearCurrentGroup = () => {
this.groupData.current = {} as GroupV2Response;
}
}
// 可以提供一个工厂函数来创建和初始化响应式数据
export function createGroupManager() {
const groupData: GroupData = reactive({
groupList: [],
current: {} as GroupV2Response,
});
return { groupData, groupManager };
}
步骤 3: 使用抽取的文件
在其他 Vue 组件中,你可以导入并使用这个抽象化了的类:
// SomeComponent.vue
<script setup lang="ts">
import { createGroupManager } from './GroupManager';
const { groupData, groupManager } = createGroupManager();
</script>
这样,你就能够在不同的组件中复用 GroupManager
类,并且每个组件可以有自己的响应式状态实例,这使得组件更独立、更易于管理。
相应外部事件
要使得 GroupManager
类在执行特定方法(如 selectThisGroup
)时能够与其他代码或组件进行交互,例如触发事件,你可以采用几种设计策略。这些策略通常涉及使用事件发射(emitting events)、回调函数或利用 Vue 的全局事件总线。下面,我将提供几种方法来实现这种交互。
方法 1: 使用事件发射(EventEmitter)
你可以使用一个事件发射器(EventEmitter)来在你的类中触发事件。这可以通过使用 Node.js 的 events
模块或一个简单的第三方事件库来实现。
安装事件库(例如 mitt
,一个轻量级的事件库):
npm install mitt
修改 GroupManager 类:
// GroupManager.ts
import { reactive } from 'vue';
import axios from 'axios';
import mitt from 'mitt';
import { GroupV2Response } from './path-to-type-definitions';
interface GroupData {
groupList: Array<GroupV2Response>;
current: GroupV2Response;
}
export class GroupManager {
public groupData: GroupData;
groupType = 1;
emitter = mitt(); // 创建事件发射器
constructor(groupData: GroupData) {
this.groupData = groupData;
}
loadGroupChildrenList = (parentGroupCode: string|null) => {
axios.post("/gallery/group/query-group-children", {
groupCode: parentGroupCode,
type: this.groupType,
}).then(resp => this.groupData.groupList = resp.data.data);
}
selectThisGroup = (group: GroupV2Response) => {
this.groupData.current = group;
this.loadGroupChildrenList(group.groupCode);
this.emitter.emit('group-selected', group); // 触发事件
}
clearCurrentGroup = () => {
this.groupData.current = {} as GroupV2Response;
this.emitter.emit('group-cleared'); // 触发事件
}
on(eventName: string, handler: (event?: any) => void) {
this.emitter.on(eventName, handler); // 提供方法来监听事件
}
off(eventName: string, handler: (event?: any) => void) {
this.emitter.off(eventName, handler); // 提供方法来移除监听
}
}
使用 GroupManager 类:
<script setup lang="ts">
import { createGroupManager } from './GroupManager';
const { groupData, groupManager } = createGroupManager();
groupManager.on('group-selected', (group) => {
console.log('Selected group:', group);
});
groupManager.on('group-cleared', () => {
console.log('Group cleared');
});
onUnmounted(() => {
// 确保在组件卸载时移除事件监听器,避免内存泄漏
groupManager.off('group-selected', handler);
groupManager.off('group-cleared', handler);
});
</script>
方法 2: 使用回调函数
另一种方法是在 GroupManager
类的构造函数中接受一个或多个回调函数作为参数,当发生特定的动作时调用这些函数。
// GroupManager.ts
export class GroupManager {
public groupData: GroupData;
groupType = 1;
private onSelectGroup: (group: GroupV2Response) => void;
private onClearGroup: () => void;
constructor(groupData: GroupData, onSelectGroup: (group: GroupV2Response) => void, onClearGroup: () => void) {
this.groupData = groupData;
this.onSelectGroup = onSelectGroup;
this.onClearGroup = onClearGroup;
}
selectThisGroup = (group: GroupV2Response) => {
this.groupData.current = group;
this.loadGroupChildrenList(group.groupCode);
this.onSelectGroup(group);
}
clearCurrentGroup = () => {
this.groupData.current = {} as GroupV2Response;
this.onClearGroup();
}
}
在这种设计中,你可以在创建 GroupManager
实例时提供具体的回调函数,使得类的行为更加灵活。这种方式适合于较为简单的交互场景,且当交互逻辑较为固定时。
通过上述两种方法,你可以使 GroupManager
类在执行其内部方法时与外部代码有效交互,根据具体的应用场景选择适合的设计模式。