Я столкнулся с интересным сценарием, в котором мне нужно точно знать, какие ключи использовались для доступа к глубоко вложенному свойству в объекте, заключенном в прокси.
Например:
form.user.address.city
Где Прокси Обертывания form
:
const form = new Proxy(source, ...)
Возможно ли в ловушке set
Proxy
узнать, что city
вложено в address
, а address
вложено в user
?
Я не хочу делать что-то вроде:
const keys = []
set(target, prop, value, receiver) {
if (typeof target[prop] === 'object') keys.push(prop)
}
Фактический вариант использования немного сложнее, чтобы быть справедливым.
form
фактически представляет модуль в магазине vuex
.
Изначально форма имела только ключ родительского уровня, пары значений и представляла собой совокупность полей из других модулей, которые можно было бы использовать для предотвращения изменения данных, существующих в хранилище vuex.
Так что это сработало безупречно:
const form = new Proxy(this.$store.getters['user'], {
get: (target, prop) => {
return _get(target, prop, undefined)
},
set: (target, prop, value) => {
this.$store.commit('user/SET_VALUE', { [prop] : value })
return true
}
})
Теперь, это работало отлично, потому что это привело к тому, что шаблон v-model
мог использовать:
v-model="form.first_name"
И мне не пришлось бы изменять user
в магазине, определяя все изменения в простом form
модуле в магазине.
Сложность этого возросла в десять раз, и этот подход использовался во многих местах, но теперь мне нужно изменить глубоко вложенные свойства.
Это коренная причина моей проблемы.
Разработка дальше -
Я также реализовал шаблон использования вложенных прокси, который не решает мою проблему, так как он только раскрывает мне свойство этого вложенного объекта, например, ловушка get
становится:
recursiveProxyGetter (target, prop) => {
if (typeof target[prop] === 'object' && target[prop] !== null) {
return new Proxy(target[prop], this.recursiveProxy)
}
return target[prop]
},
И ловушка set
становится:
recursiveProxySetter(target, prop, value) => {
if (typeof target[prop] === 'object' && target[prop] !== null) {
return new Proxy(target[prop], this.recursiveProxy)
}
this.updateFormValue(prop, value)
return true
}
Где recursiveProxy
определяется как простое свойство моего миксина:
recursiveProxy: any = {
get: this.recursiveProxyGetter,
set: this.recursiveProxySetter
}
И инициализируется тысяча:
form: {... a bunch of typescript unions} = new Proxy(this.$store.getters['user'], this.recursiveProxy)