如果 Vue 3 引用是对象的 属性,则它们的行为会有所不同
Vue 3 refs behave differently if they are the property of an object
当使用 Vue 3 的 Composition API 时,我注意到在作为对象的 属性 访问模板引用时,它们在模板中的行为有所不同。我认为 this example in the SFC Playground 对此进行了最好的总结,但这是关键代码(来自单个文件组件):
<script>
import { ref } from 'vue';
export default {
setup() {
const wut = ref(false);
const obj = { wut };
return {
wut,
obj,
};
},
};
</script>
<template>
<!-- obj.wut - false -->
<h3>obj.wut - {{ obj.wut }}</h3>
<!-- !!obj.wut - true -->
<h3>!!obj.wut - {{ !!obj.wut }}</h3>
<!-- obj.wut.value - false -->
<h3>obj.wut.value - {{ obj.wut.value }}</h3>
<!-- !!obj.wut.value - false -->
<h3>!!obj.wut.value - {{ !!obj.wut.value }}</h3>
<!-- does display -->
<h3 v-if="obj.wut">display logic for this: v-if="obj.wut"</h3>
<!-- does not display -->
<h3 v-if="!obj.wut">display logic for this: v-if="!obj.wut"</h3>
<!-- typeof obj.wut - object -->
<h3>typeof obj.wut - {{ typeof obj.wut }}</h3>
</template>
谁能解释为什么它在某些情况下似乎将 ref 视为对象,而在其他情况下解释其值?这是错误还是设计使然?
简短回答:这是设计。
长答案:
请检查Vue3 Guide -> Advanced Guides -> Reactivity -> Reactivity Fundamentals -> Ref unwrapping
Ref Unwrapping
When a ref is returned as a property on the render context (the object returned from setup()) and accessed in the template, it automatically shallow unwraps the inner value. Only the nested ref will require .value
in the template:
在你的例子template中,obj.wut
是一个ref对象,wut
是一个展开的原始值(布尔值)
额外内容:
- 在您的示例中,
obj.wut
在页面中呈现为 false
,似乎它在没有 .value
的情况下也能正常工作。那是因为vue中的一个toDisplayString
function,它取了ref对象(obj.wut
),它对ref对象的内部值做了JSON.stringify
。如果 wut
的值为 a string
(const wut = ref('a string');
),您会在呈现的页面中看到额外的双引号,例如 "a string"
- 文档中还有另一个提示,您可以将对象包装在
reactive
(const obj = reactive({ wut })
) 中以在模板中访问未包装的值。
当使用 Vue 3 的 Composition API 时,我注意到在作为对象的 属性 访问模板引用时,它们在模板中的行为有所不同。我认为 this example in the SFC Playground 对此进行了最好的总结,但这是关键代码(来自单个文件组件):
<script>
import { ref } from 'vue';
export default {
setup() {
const wut = ref(false);
const obj = { wut };
return {
wut,
obj,
};
},
};
</script>
<template>
<!-- obj.wut - false -->
<h3>obj.wut - {{ obj.wut }}</h3>
<!-- !!obj.wut - true -->
<h3>!!obj.wut - {{ !!obj.wut }}</h3>
<!-- obj.wut.value - false -->
<h3>obj.wut.value - {{ obj.wut.value }}</h3>
<!-- !!obj.wut.value - false -->
<h3>!!obj.wut.value - {{ !!obj.wut.value }}</h3>
<!-- does display -->
<h3 v-if="obj.wut">display logic for this: v-if="obj.wut"</h3>
<!-- does not display -->
<h3 v-if="!obj.wut">display logic for this: v-if="!obj.wut"</h3>
<!-- typeof obj.wut - object -->
<h3>typeof obj.wut - {{ typeof obj.wut }}</h3>
</template>
谁能解释为什么它在某些情况下似乎将 ref 视为对象,而在其他情况下解释其值?这是错误还是设计使然?
简短回答:这是设计。
长答案:
请检查Vue3 Guide -> Advanced Guides -> Reactivity -> Reactivity Fundamentals -> Ref unwrapping
Ref Unwrapping
When a ref is returned as a property on the render context (the object returned from setup()) and accessed in the template, it automatically shallow unwraps the inner value. Only the nested ref will require
.value
in the template:
在你的例子template中,obj.wut
是一个ref对象,wut
是一个展开的原始值(布尔值)
额外内容:
- 在您的示例中,
obj.wut
在页面中呈现为false
,似乎它在没有.value
的情况下也能正常工作。那是因为vue中的一个toDisplayString
function,它取了ref对象(obj.wut
),它对ref对象的内部值做了JSON.stringify
。如果wut
的值为a string
(const wut = ref('a string');
),您会在呈现的页面中看到额外的双引号,例如"a string"
- 文档中还有另一个提示,您可以将对象包装在
reactive
(const obj = reactive({ wut })
) 中以在模板中访问未包装的值。