123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178 |
- import { reactive, watch } from "vue";
- import { Attrib, GetSetPick } from "../type";
- import { inRevise, toRawType } from "./public";
- import { Shape } from "konva/lib/Shape";
- import { Group } from "konva/lib/Group";
- export const setShapeConfig = <T extends Group | Shape>(
- shape: T,
- config: GetSetPick<T>
- ) => {
- for (const key in config) {
- if (typeof shape[key as any] === "function") {
- shape[key as any](config[key]);
- }
- }
- };
- export const getChangePart = <T>(newIds: T[], oldIds: T[] = []) => {
- const addPort = newIds.filter((newId) => !oldIds.includes(newId));
- const delPort = oldIds.filter((oldId) => !newIds.includes(oldId));
- const holdPort = oldIds.filter((oldId) => newIds.includes(oldId));
- return { addPort, delPort, holdPort };
- };
- export const getChangeAllPoart = <T extends Attrib>(
- newAttribs: T[],
- oldAttribs: T[]
- ) => {
- const newIds = newAttribs.map(({ id }) => id);
- const oldIds = oldAttribs.map(({ id }) => id);
- const ports = getChangePart(newIds, oldIds);
- // 数组子项引用变化
- const changePort = newAttribs
- .filter(
- (newAttrib) =>
- !oldAttribs.includes(newAttrib) && oldIds.includes(newAttrib.id)
- )
- .map((attrib) => attrib.id);
- oldAttribs = newAttribs;
- return { ...ports, changePort };
- };
- type AttribsChange = ReturnType<typeof getChangePart> & {
- changePort: string[];
- };
- export const watchAttribs = (
- attribs: Attrib[],
- callback: (data: AttribsChange) => void,
- immediate = true
- ) => {
- return watch(
- () => [...attribs],
- (newAttribs, oldAttribs = []) => {
- callback(getChangeAllPoart(newAttribs, oldAttribs));
- },
- { immediate, flush: "sync" }
- );
- };
- export const deptComputed = <T extends Record<string, any>>(
- getter: () => T
- ) => {
- const data = reactive(getter());
- const stop = watch(getter, (newData) => {
- if (inRevise(data, newData)) {
- if (Array.isArray(newData)) {
- newData.forEach((item, ndx) => {
- data[ndx] = item;
- });
- } else {
- Object.keys(data).forEach((key) => delete data[key]);
- Object.assign(data, newData);
- }
- }
- });
- return {
- data: data as T,
- stop,
- };
- };
- export const partialComputed = <T extends Attrib>(getter: () => T[]) => {
- const data = reactive(getter()) as T[];
- const stop = watch(getter, (newData, oldData) => {
- const { addPort, delPort, changePort } = getChangeAllPoart(
- newData,
- oldData
- );
- for (const delId of delPort) {
- const ndx = data.findIndex((i) => i.id === delId);
- ~ndx && data.splice(ndx, 1);
- }
- for (const addId of addPort) {
- const addItem = newData.find((i) => i.id === addId);
- addItem && data.push(addItem);
- }
- for (const changeId of changePort) {
- const dataNdx = data.findIndex((i) => i.id === changeId);
- const newDataNdx = newData.findIndex((i) => i.id === changeId);
- if (inRevise(data[dataNdx], newData[newDataNdx])) {
- data[dataNdx] = newData[newDataNdx];
- }
- }
- });
- return {
- data,
- stop,
- };
- };
- export const depPartialUpdate = <T>(newData: T, oldData: T): T => {
- if (!inRevise(newData, oldData)) {
- return oldData;
- }
- if (!oldData) {
- return newData;
- }
- const nData = newData as any,
- oData = oldData as any;
- const type = toRawType(nData);
- if (toRawType(oldData) !== type) {
- return newData;
- }
- switch (type) {
- case "Array":
- if (nData[0]?.id || oData[0]?.id) {
- var { changePort, addPort, delPort } = getChangeAllPoart(nData, oData);
- addPort.forEach((qid) => {
- oData.push(nData.find(({ id }) => id === qid));
- });
- delPort.forEach((dId) => {
- const ndx = oData.findIndex(({ id }) => id === dId);
- ~ndx && oData.splice(ndx, 1);
- });
- changePort.forEach((cId) => {
- const nItem = nData.find(({ id }) => id === cId);
- const ndx = oData.findIndex(({ id }) => id === cId);
- oData[ndx] = depPartialUpdate(nItem, oData[ndx]);
- });
- } else {
- for (let i = 0; i < nData.length; i++) {
- oData[i] = depPartialUpdate(nData[i], oData[i]);
- }
- while (oData.length !== nData.length) {
- oData.pop();
- }
- }
- break;
- case "Object":
- const oKeys = Object.keys(oData).sort();
- const nKeys = Object.keys(nData).sort();
- var { addPort, delPort, holdPort } = getChangePart(nKeys, oKeys);
- for (let i = 0; i < holdPort.length; i++) {
- oData[oKeys[i]] = depPartialUpdate(
- nData[holdPort[i]],
- oData[holdPort[i]]
- );
- }
- addPort.forEach((key) => (oData[key] = nData[key]));
- delPort.forEach((key) => delete oData[key]);
- break;
- default:
- return newData;
- }
- return oldData;
- };
|