如果 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 引用是对象的属性,则它们的行为会有所不同 的相关文章

  • Vue Router - 使用 Vue 2 Composition API 获取路由参数

    我正在使用Vue 2 组合 API https github com vuejs composition api并想从我的 Vue Router 访问路由参数setup method 如中所述Vue 路由器文档 https next rou
  • workbox webpack 插件从预缓存清单中排除文件夹

    我正在将 workbox webpack 插件与 vue cli 3 一起使用 并且我想将文件夹中的文件排除在外 以免添加到预缓存清单中 请参阅下面我当前的文件结构 src 资产 CSS 壳文件1 svg文件2 svg文件3 svg svg
  • Vue 组件方法未在动态 HTML 中的事件上运行

    我正在尝试动态创建一些 HTML 内容并将 Vue 组件方法绑定到元素上的事件 然而这不起作用 下面是问题的描述和测试用例的片段 重现问题的步骤 Click 点我1 观察控制台 Click 切换工具提示的弹出框 Click 点我2 观察控制
  • 如何更改 Vuetify 日历日期格式

    我正在尝试在以下 Vuetify 日历上启用输入事件 https github com vuetifyjs vuetify blob master packages docs src examples calendars complex e
  • 使用 Vercel 进行 Vue.js 历史记录模式的服务器配置?

    我设置了一个非常基本的 Vue js 应用程序 主要使用这些步骤 https auth0 com docs quickstart spa vuejs 01 login 当我将路由器添加到该项目时 它询问我是否要使用历史模式 我说是 现在我正
  • 如何使用Vue3中的ref访问父组件中的子组件方法?

    我正在尝试使用 vue3 和 ref 方法访问父组件中的子方法 但它返回一个错误 未捕获的类型错误 addNewPaper value savePaper 不是函数 下面是我的代码 请指导我哪里错了 子组件
  • 如何在 vuejs 中防止/停止点击传播

    我有一个递归列表 树 每个元素都有一个 click sayHello el id 现在的问题是 因为它是一个嵌套列表 例如 list element 0 01 list el 1 01 list el 2 01 list el 1 02 l
  • 如何隔离 Vuetify 全局样式

    我已经开始在旧的现有项目中将 Vue js 与 Vuetify 结合使用 所以我没有重写所有前端 我只是导入了Vue并替换了一些部分 然后我注意到一个非常意想不到的行为 Vuetify 具有常见类的全局样式 例如 title它不仅影响整个页
  • 使用 Javascript 在前端创建基本 URL(开发、API 和生产)

    无论开发和部署如何 如何制作适用于 http https localhost 端口和实际域的基本 url 我想创建一个可以在所有场景或条件下工作的基本 url 无论 http https 协议 端口 本地主机和实际域如何 无论是在开发中还是
  • Vuejs ssr 检查用户是否针对每个请求进行了身份验证

    我正在为我的应用程序使用这个 ssr 样板 https github com vuejs vue hackernews 2 0 https github com vuejs vue hackernews 2 0 我不知道如何实现逻辑来检查每
  • Web 扩展中共享 vuex 状态(死对象问题)

    我正在尝试在网络扩展中使用共享的 vue js 状态 状态存储在后台脚本的 DOM 中并呈现在弹出页面中 第一次尝试 我的第一次尝试是使用一个没有 vuex 的简单商店 背景 js var store count 0 popup js br
  • Asyncdata 与 Fetch 之间的区别

    获取数据和异步数据之间的确切区别是什么 官方文档是这么说的 异步数据 您可能想要获取数据并在服务器端呈现它 Nuxt js 添加 asyncData 方法 让您可以在之前处理异步操作 设置元件数据 异步数据每次在加载组件之前调用 仅适用于
  • 在 ES6 中使用 import 和 require 的正确方法是什么?

    关于 import 和 require 及其差异有多个问题 像这些 JavaScript 中的 import 和 require 有什么区别 https stackoverflow com questions 51373933 what i
  • 如何在Vue中提交表单,重定向到新路由并传递参数?

    我正在使用 Nuxt 和 Vue 我正在尝试提交表单 将用户重定向到包含提交的参数的新路由 发送 API 请求以获取一些数据 然后渲染该数据 我通过简单地将表单操作设置为新路径并手动将所有 URL 参数添加到 API 请求来实现此目的 首先
  • Vue js - 在同一级别的两个组件内传递数据

    我有需要从一个传递的数据component1到另一个component2 我不使用vuex or router 组件树 Parent Component1 Component2 从一开始component1我发出 ajax 请求 检索信息并
  • vue如何检测页面是否刷新?

    我尝试这样 created window addEventListener beforeunload function event event returnValue Write something this router push 像这样
  • Mapbox JS SDK CSS样式表导致地图消失

    我在 VueJS 应用程序中使用 Mapbox JavaScript SDK 我可以毫无问题地显示地图 现在我想添加一些标记 我懂了在本页 https docs mapbox com mapbox gl js api 您需要先导入 CSS
  • 从组件传递数据

    我对 Vue 相当陌生 我正在尝试将数据从组件传递到视图 我不确定我是否在使用props正确的 我有一个对话框 当我保存时 我想将数据插入数据库 我也想重复使用addCustomer function 这就是为什么我没有将该函数放置在组件中
  • Vue中有类似React.Fragment的东西吗?

    在 React 中我可以做这样的事情 parent component export default return div div 1 div div
  • 在渲染组件之前从 api 获取数据

    我在渲染页面之前发送 2 个 api 请求 const Profile template profile attributes null photos data function return attributes Profile attr

随机推荐