如果 Vue 3 引用是对象的属性,则它们的行为会有所不同

2023-12-26

使用 Vue 3 的 Composition API 时,我注意到模板内部的引用在作为对象的属性进行访问时的行为有所不同。我认为这是最好的总结SFC Playground 中的这个示例 https://sfc.vuejs.org/#eyJBcHAudnVlIjoiPHNjcmlwdD5cbmltcG9ydCB7IHJlZiB9IGZyb20gJ3Z1ZScgIFxuZXhwb3J0IGRlZmF1bHQge1xuICBzZXR1cCgpe1xuICAgIGNvbnN0IHd1dCA9IHJlZih0cnVlKTtcbiAgICBjb25zdCBvYmogPSB7d3V0fVxuICAgIGNvbnN0IGNoYW5nZVd1dCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgIHd1dC52YWx1ZSA9ICF3dXQudmFsdWU7XG4gICAgfTtcbiAgICByZXR1cm4ge1xuICAgICAgd3V0LCBvYmosIGNoYW5nZVd1dFxuICAgIH0gIFxuICB9XG59XG48L3NjcmlwdD5cblxuPHRlbXBsYXRlPlxuIDxoMT53dXQgaXMgYSByZWYoKS4gV2hlbiBhY2Nlc3NpbmcgaXQgd2l0aGluIGEgdGVtcGxhdGUsIGl0IGJlaGF2ZXMgZGlmZmVyZW50bHkgaWYgaXQncyBpbiBhbiBvYmplY3Q8L2gxPlxuICA8YnV0dG9uIEBjbGljaz1cImNoYW5nZVd1dFwiPkNoYW5nZSBXdXQ8L2J1dHRvbj5cbiAgPGgxPkFjY2Vzc2luZyB3dXQgZGlyZWN0bHk8L2gxPlxuICA8aDM+d3V0IC0ge3sgd3V0IH19PC9oMz5cbiAgPGgzPiEhd3V0IC0ge3sgISF3dXQgfX08L2gzPlxuICA8aDM+d3V0LnZhbHVlIC0ge3sgd3V0LnZhbHVlIH19PC9oMz5cbiAgPGgzPiEhd3V0LnZhbHVlIC0ge3sgISF3dXQudmFsdWUgfX08L2gzPlxuICA8aDMgdi1pZj1cInd1dFwiPmRpc3BsYXkgbG9naWMgZm9yIHRoaXM6IHYtaWY9XCJ3dXRcIjwvaDM+XG4gIDxoMyB2LWlmPVwiIXd1dFwiPmRpc3BsYXkgbG9naWMgZm9yIHRoaXM6IHYtaWY9XCIhd3V0XCI8L2gzPlxuICA8aDM+dHlwZW9mIHd1dCAtIHt7IHR5cGVvZiB3dXQgfX08L2gzPlxuXG4gIDxoMT5BY2Nlc3Npbmcgd3V0IGFzIGEgcHJvcGVydHkgb2YgYW4gb2JqZWN0PC9oMT5cbiAgPGgzPm9iai53dXQgLSB7eyBvYmoud3V0IH19PC9oMz5cbiAgPGgzPiEhb2JqLnd1dCAtIHt7ICEhb2JqLnd1dCB9fTwvaDM+XG4gIDxoMz5vYmoud3V0LnZhbHVlIC0ge3sgb2JqLnd1dC52YWx1ZSB9fTwvaDM+XG4gIDxoMz4hIW9iai53dXQudmFsdWUgLSB7eyAhIW9iai53dXQudmFsdWUgfX08L2gzPlxuICA8aDMgdi1pZj1cIm9iai53dXRcIj5kaXNwbGF5IGxvZ2ljIGZvciB0aGlzOiB2LWlmPVwib2JqLnd1dFwiPC9oMz5cbiAgPGgzIHYtaWY9XCIhb2JqLnd1dFwiPmRpc3BsYXkgbG9naWMgZm9yIHRoaXM6IHYtaWY9XCIhb2JqLnd1dFwiPC9oMz5cbiAgPGgzPnR5cGVvZiBvYmoud3V0IC0ge3sgdHlwZW9mIG9iai53dXQgfX08L2gzPlxuXG48L3RlbXBsYXRlPlxuPHN0eWxlPlxuICBoMntcbiAgICBib3JkZXI6IDFweCBzb2xpZCAjOTk5O1xuICAgIHBhZGRpbmc6NHB4O1xuICB9XG48L3N0eWxlPiIsImltcG9ydC1tYXAuanNvbiI6IntcbiAgXCJpbXBvcnRzXCI6IHtcbiAgICBcInZ1ZVwiOiBcImh0dHBzOi8vc2ZjLnZ1ZWpzLm9yZy92dWUucnVudGltZS5lc20tYnJvd3Nlci5qc1wiXG4gIH1cbn0ifQ==,但这是关键代码(来自单个文件组件):

    <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 指南 -> 高级指南 -> 反应性 -> 反应性基础知识 -> 引用展开 https://v3.vuejs.org/guide/reactivity-fundamentals.html#ref-unwrapping

参考解包

当 ref 作为渲染上下文(从 setup() 返回的对象)上的属性返回并在模板中访问时,它会自动浅层解包内部值。只有嵌套引用需要.value在模板中:

在你的例子中template, the obj.wut是一个 ref 对象,wut是一个未包装的原始值(布尔值)

Extras:

  1. 在你的例子中,obj.wut被渲染为false在页面中,似乎它可以在没有.value。那是因为一个toDisplayString功能 https://github.com/vuejs/vue-next/blob/ccb6651b12af6d1b43e2391cef77fd0bb73e49bd/packages/shared/src/toDisplayString.ts#L21在 vue 中,它采用 ref 对象(obj.wut),确实如此JSON.stringify关于 ref 对象的内部值。如果值wut is a string (const wut = ref('a string');),您将在渲染的页面中看到它周围有额外的双引号,例如"a string"
  2. 文档中还有另一个提示,您可以将对象包装在reactive (const obj = reactive({ wut })) 来访问模板中展开的值。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如果 Vue 3 引用是对象的属性,则它们的行为会有所不同 的相关文章

随机推荐