The original data pollution
Vue version
latest(3.2.39)
Link to minimal reproduction
https://codepen.io/missflower-the-animator/pen/NWMYaEw
Steps to reproduce
Open the console options
What is expected?
Reactive should not be triggered when raw data is assigned
What is actually happening?
Reactive is triggered when raw data is assigned
System Info
System:
OS: macOS 12.1
CPU: (10) x64 Apple M1 Pro
Memory: 727.07 MB / 32.00 GB
Shell: 5.8 - /bin/zsh
Binaries:
Node: 14.15.1 - ~/.nvm/versions/node/v14.15.1/bin/node
Yarn: 1.22.18 - ~/.nvm/versions/node/v14.15.1/bin/yarn
npm: 6.14.8 - ~/.nvm/versions/node/v14.15.1/bin/npm
Browsers:
Chrome: 105.0.5195.125
Safari: 15.2
npmPackages:
vue: workspace:* => 3.2.39
Any additional comments?
test('The value of the shallow responsive setting is deep responsive and should not trigger responsive', () => {
const original: { a: number; b: any } = {
a: 1,
b: ''
}
const observed = reactive({
c: 2
})
const shadowObj = shallowReactive(original)
shadowObj.b = observed as unknown as any
effect(() => {
console.log(original.b.c)
})
original.b.c = 3
})
test('The value of the deep responsive setting is shallow responsive and should not trigger responsive, () => {
const original: { a: number; b: any } = {
a: 1,
b: ''
}
const observed = shallowReactive({
c: 2
})
const obj = reactive(original)
obj.b = observed as unknown as any
effect(() => {
console.log(original.b.c)
})
original.b.c = 3
})
这有什么问题吗?shallowReactive 只会对对象第一层做响应式化处理,而 reactive 则会根据你访问的 key 是否为对象递归调用 reactvie 再次做响应式处理,你的例子中把一个 reactive 赋值到 b 上,不就是手动给 b 的值做了一次响应式处理?然后在 effect 中访问被收集,赋值时又被触发
original is a non-reactive object
, orginal.b
is a reactive object after you assinged it here:
shadowObserved.b = observed;
The effect observes this reactive object.
@baiwusanyu-c effect中是访问的原始数据original上面的属性 这里应该不被触发响应式才对啊 这样不是造成了原始数据的污染吗
const shadowObserved = shallowReactive(original);
shadowObserved.b = observed;
这一句已经修改了原始数据了,原始数据上没有 b,你通过代理对象访问 b并设置了值,这里是一个set操作,代理对象会作用到原始对象上,相当于给原始对象创建了一个 b,值是 observed
@baiwusanyu-c effect中是访问的原始数据original上面的属性 这里应该不被触发响应式才对啊 这样不是造成了原始数据的污染吗
const shadowObserved = shallowReactive(original); shadowObserved.b = observed;
这一句已经修改了原始数据了,原始数据上没有 b,你通过代理对象访问 b并设置了值,这里是一个set操作,代理对象会作用到原始对象上,相当于给原始对象创建了一个 b,值是 observed
是的 但是我觉得应该被toRaw包裹 如果是reactive的属性被设置reactive对象就不会出现原始数据污染问题
original is a non-reactive object
,orginal.b
is a reactive object after you assinged it here:shadowObserved.b = observed;
The effect observes this reactive object.
@LinusBorg Please take a look at the discussion above
I dont speak chinese so rely on google but:
You seem to expect that assignments to a shallow reactive are ran through toRaw()
.
Thats not how this is designed. Any changes to properties of a shallow reactive are done as-is. No unwrapping is happening. That's documented.
And its good like that. Because now you can decide wether to convert the value to raw before assigning it. You now have the choice of assinging a reactive or a plain raw value.
I dont speak chinese so rely on google but:
You seem to expect that assignments to a shallow reactive are ran through
toRaw()
.Thats not how this is designed. Any changes to properties of a shallow reactive are done as-is. No unwrapping is happening. That's documented.
And its good like that. Because now you can decide wether to convert the value to raw before assigning it. You now have the choice of assinging a reactive or a plain raw value.
ok, thanks for your answer