wal*_*lox 2 vue.js vuejs3 vue-composition-api
在玩 Vue 3 反应性时,我遇到了一种我无法解释的行为。
我创建了一个ref
原语。检查isRef
一下,显然返回了true
。但是当作为 a 传递给子组件时prop
,isRef()
也会isReactive()
返回false
。为什么 ?
另外,即使它们都返回false
,如果值发生变化,我在子组件中添加的这个道具的观察者也会被触发。如果监视的值不是ref
or ,它如何触发reactive
?
这是父级和子级的代码片段:
家长.vue
let foo = ref(0);
function changeFoo() {
foo.value++;
}
console.log("parent check is reactive?", isReactive(foo)); // retruns false
console.log("parent check is ref?", isRef(foo)); // retruns true
watch(foo, (value, oldValue) => {
console.log("foo changing from", oldValue, "to ", value);
});
Run Code Online (Sandbox Code Playgroud)
儿童.vue
const props = defineProps<{
foo: number;
}>();
console.log("child check is reactive?",isReactive(props), isReactive(props.foo)); // returns true false
console.log("child check is ref ?",isRef(props), isRef(props.foo)); // returns false false // Question 1: Why props.foo is not a Ref ?
watch(props, (value, oldValue) => {
console.log("props changing from", oldValue, " to ", value);
});
watch(()=>props.foo, (value, oldValue) => {
// Question 2: Why this Watcher detects changes of "foo" without it being a ref nor reactive ?
console.log("props.foo changing from ", oldValue, " to ", value);
});
Run Code Online (Sandbox Code Playgroud)
此处还有 Vue SFC Playground 的链接
额外问题:当foo
传递给子组件中使用的可组合项时,除非我们通过 toRef 传递,否则不会触发可组合项内的观察程序,但如果是 ref/reactive 对象,foo
则不需要此额外步骤。foo
为什么基元需要这个加法步骤?
但是当作为 prop 传递给子组件时, isRef() 和 isReactive() 返回 false。
您在这里只讲述了故事的一半,正如您自己的评论实际上表明的那样:
console.log("child check is reactive?",isReactive(props), isReactive(props.foo)); // returns true false
Run Code Online (Sandbox Code Playgroud)
isReactive(props)
确实返回 true,因为整个props
对象(包装foo
)是反应性的。父级对 进行的任何更新foo
都会作为更新的对象传递给子级props
。这确实props.foo
不是 ref/reactive,因为它不需要这样。只要props
有反应props.foo
就会更新
观察者能够在更改时激活,props.foo
因为您实际上使用了特殊的语法,其中您向观察者传递了一个“getter”,专门用于观察反应对象的属性(在您的情况下: props )。Vue 文档中有一个示例说了同样的事情。
如果您需要分配props.foo
给它自己的反应变量,比如传递给可组合项,那么就可以使用 toRef 。
// reactive but not synced with props.foo
const newFoo = ref(props.foo)
// reactive AND synced with props.foo
const newFoo = toRef(props, 'foo')
Run Code Online (Sandbox Code Playgroud)
正如我在上面的评论中指出的,如果您使用 just 创建一个新变量ref
,它将是反应性的,但它不会与其源属性同步,即第一个newFoo
在更新时不会反应性更新props.foo
,但第二个newFoo
会。Vue 文档中对此也有很好的解释
归档时间: |
|
查看次数: |
2888 次 |
最近记录: |