该思路 是通过MVC 数据层 控制层这种方式,来实现数据量比较大的页面交互效果
目录结构
1. 数据层 model.ts
/**
* 数据层
*/
import { DataSourceType, IModelType } from './interface';
import Event from './event';
export default class Model implements IModelType {
// 页面需要变量数据
private dataSource: DataSourceType | null = null;
private static model: IModelType | null = null;
constructor(payload: DataSourceType) {
this.dataSource = payload
}
public static getInstance(payload: DataSourceType) {
if (!this.model) {
this.model = new Model(payload);
}
return this.model;
}
public setValue(key: string, val: any) {
(this as any).dataSource[key] = val
this.update((this as any).dataSource)
}
public getValue(key: string) {
const current = (this as any).dataSource[key];
if (current) {
return current;
}
return null;
}
public getValues(): any {
return this.dataSource
}
public update(payload: DataSourceType) {
this.dataSource = payload
Event.dispatchEvent('change', payload)
}
}
2. 数据变更触发监听器,发布订阅 event.ts
/**
* 数据变更触发监听器,发布订阅
*/
import { IHandleType } from './interface';
export default class Event {
public static handlers: IHandleType = {}
public static addEventListener (type: any, handler: any) {
if (!(type in this.handlers)) {
this.handlers[type] = []
}
this.handlers[type].push(handler)
}
public static dispatchEvent (type: any, ...params: any) {
if (!(type in this.handlers)) {
return new Error('未注册该事件')
}
this.handlers[type].forEach((handler: any) => {
handler(...params)
})
}
public static removeEventListener (type: any, handler: any) {
if (!(type in this.handlers)) {
return new Error('无效事件')
}
if (!handler) {
delete this.handlers[type]
} else {
const idx = this.handlers[type].findIndex((ele: any) => ele === handler)
if (idx === undefined) {
return new Error('无该绑定事件')
}
this.handlers[type].splice(idx, 1)
if (this.handlers[type].length === 0) {
delete this.handlers[type]
}
}
}
}
3. 数据 ui 交互中间层 controller.ts
/**
* 数据 ui 交互中间层
*/
import { IModelType, IControllerType, DataSourceType } from './interface';
import Model from './model';
export default class Controller implements IControllerType {
private readonly dataSource: DataSourceType | null = null;
private model: IModelType | null = null;
private static controller: IControllerType | null = null;
constructor(payload: DataSourceType) {
this.dataSource = payload
}
public static getInstance(payload: DataSourceType | null) {
if (!this.controller) {
this.controller = new Controller(payload as any);
}
return this.controller;
}
public init() {
this.model = Model.getInstance((this as any).dataSource);
}
public getValue(key: string) {
return (this as any).model.getValue(key);
}
public setValue(key: string, val: any) {
(this as any).model.setValue(key, val);
}
public getValues() {
return (this as any).model.getValues();
}
public update(payload: DataSourceType) {
(this as any).model.update(payload);
}
}
4. 定义接口 interface.ts
export type StateInfoType = {
current_state?: string;
errors: any[];
partner_edited?: boolean;
}
export interface SubmissionItemType {
client_id?: string;
id?: number | string;
default_locale_code?: string;
locale_code: string;
state_info: StateInfoType;
}
export interface Type {
getValue: (k: any) => string;
setValue: (k: string, v: string | boolean) => void;
getValues: () => DataSourceType;
update: (payload: DataSourceType) => void;
}
export interface IControllerType extends Type {
init: () => void
}
export interface IModelType extends Type {}
export interface IHandleType {
[k: string]: any
}
export interface DataSourceType {
[key: string]: any
}
export interface DesignDataType {
}
export interface DesignContextProps {
data: DesignDataType;
cloneData: DesignDataType;
handleSetValue: any;
handleUpdateValue?: any;
handleCloneDefaultData?: any;
}
export interface RuleDataType {
[x: string]: any;
rule_scope_list: any;
spu_sku_info: {};
shop_rule_id?: number | string | undefined;
target_group: number | string
}
export interface RuleContextProps {
data: RuleDataType;
handleSetValue: any;
handleUpdateValue?: any;
}
5. 页面调用
6. 通过provider 的方式传递给子组件
父组件
子组件