From 5d749217298773b15c83edb8787da87173c539df Mon Sep 17 00:00:00 2001 From: the1812 Date: Sat, 19 Feb 2022 17:18:53 +0800 Subject: [PATCH 1/2] Revert a4f7b6e (#2928) --- .../style/custom-navbar/settings/NavbarSettings.vue | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/registry/lib/components/style/custom-navbar/settings/NavbarSettings.vue b/registry/lib/components/style/custom-navbar/settings/NavbarSettings.vue index 73a0b8674..60a33bf1a 100644 --- a/registry/lib/components/style/custom-navbar/settings/NavbarSettings.vue +++ b/registry/lib/components/style/custom-navbar/settings/NavbarSettings.vue @@ -89,7 +89,7 @@ import { VLoading, } from '@/ui' import { addComponentListener } from '@/core/settings' -import { deleteValue, dqa } from '@/core/utils' +import { dqa } from '@/core/utils' import { SortableJSLibrary } from '@/core/runtime-library' import { SortableEvent } from 'sortablejs' import { getData } from '@/plugins/data' @@ -121,8 +121,7 @@ export default Vue.extend({ open: false, padding: navbarOptions.padding, rendered, - // order: navbarOptions.order, - hidden: [...navbarOptions.hidden], + hidden: navbarOptions.hidden, loaded: false, } }, @@ -173,13 +172,11 @@ export default Vue.extend({ this.rendered.items = sortItems(rendered.items, ordersMap) }, toggleVisible(item: CustomNavbarItem) { - if (this.hidden.includes(item.name)) { - deleteValue(this.hidden, it => it === item.name) - deleteValue(navbarOptions.hidden, it => it === item.name) + if (navbarOptions.hidden.includes(item.name)) { + lodash.pull(navbarOptions.hidden, item.name) item.hidden = false console.log('delete', item.name) } else { - this.hidden.push(item.name) navbarOptions.hidden.push(item.name) item.hidden = true console.log('add', item.name) From 1bdea9e0dd0802dc39bfdfbc9779fd4c6ec3f572 Mon Sep 17 00:00:00 2001 From: the1812 Date: Sat, 19 Feb 2022 17:19:14 +0800 Subject: [PATCH 2/2] Fix proxy on prototypes (fix #2928) --- src/core/settings/index.ts | 38 +++++++++++++++++++++++++++++++------- 1 file changed, 31 insertions(+), 7 deletions(-) diff --git a/src/core/settings/index.ts b/src/core/settings/index.ts index 11af05563..8d00fd10c 100644 --- a/src/core/settings/index.ts +++ b/src/core/settings/index.ts @@ -77,9 +77,15 @@ const settingsChangedHandler = ( } } -// 建立 Proxy +/** 标识经由 `createProxy` 控制的对象 */ export const isProxy = Symbol('isProxy') -export const createProxy = (targetObj: any, valueChangeListener: ValueChangeListener) => { + +/** + * 为目标对象创建深层 Proxy + * @param targetObj 目标对象 + * @param valueChangeListener 对象自身属性变化时的回调函数 + */ +export const createProxy = (targetObj: any, valueChangeListener?: ValueChangeListener) => { const applyProxy = (obj: any, rootProp?: Property, propPath: Property[] = []) => { for (const [key, value] of Object.entries(obj)) { if (typeof value === 'object' && !(value instanceof RegExp)) { @@ -94,21 +100,39 @@ export const createProxy = (targetObj: any, valueChangeListener: ValueChangeList return o[prop] }, set(o, prop, value) { - if (/* !(prop in o) && */typeof value === 'object' + const oldValue = o[prop] + const isImplicitProp = ( + !Object.prototype.hasOwnProperty.call(o, prop) && oldValue !== undefined + ) + if (unsafeWindow.proxyDebug) { + console.log({ isImplicitProp, prop, value }) + } + /** + * 是否对 value 启用深层 Proxy + * - 是 Object (或 Array) + * - 不能是 RegExp + * - 不能是已经启用过的 + * - 不能是上游原型链里的 + */ + const deep = ( + typeof value === 'object' && !(value instanceof RegExp) && !(value[isProxy] === true) - ) { + && !isImplicitProp + ) + if (deep) { value = applyProxy(value, rootProp || prop, [...propPath, prop]) } - const oldValue = o[prop] o[prop] = value - valueChangeListener(value, oldValue, rootProp || prop, [...propPath, prop]) + if (!isImplicitProp) { + valueChangeListener?.(value, oldValue, rootProp || prop, [...propPath, prop]) + } return true }, deleteProperty(o, prop) { const oldValue = o[prop] delete o[prop] - valueChangeListener(undefined, oldValue, rootProp || prop, [...propPath, prop]) + valueChangeListener?.(undefined, oldValue, rootProp || prop, [...propPath, prop]) return true }, })