在Vue 3中,`v-if`不能用于从可组合函数返回的`ref`值。

huangapple go评论83阅读模式
英文:

On vue 3 v-if not working for ref value returned from composable

问题

我创建了一个带有响应式布尔值的可组合对象。出于某种原因,在模板的v-if中,响应式布尔值只能与.value一起使用。它不会在模板内自动解包。

但是,如果我直接在Vue组件上使用布尔引用,它会起作用。我在这里复制了它。

代码:

// useToggle.ts 文件
import { ref } from "vue";

const visible = ref(true);

export function useToggle() {
  function toggle() {
    visible.value = !visible.value;
  }

  function close() {
    visible.value = false;
  }

  return {
    visible,
    toggle,
    close,
  };
}


// App.vue 文件
<script setup lang="ts">
import { ref } from "vue";
import { useToggle } from "./useToggle";

const visible = ref(true);
const t = useToggle();
</script>

<template>
  <button @click="visible = !visible">切换本地</button>
  <div v-if="visible">本地</div>

  <button @click="t.toggle">切换全局不使用.value</button>
  <div v-if="t.visible">全局(这不起作用)</div>
  <div v-if="t.visible.value">全局(这不起作用)</div>

  {{t.visible}}(但这个会更新)

</template>

我不明白为什么v-if不起作用相同。我该怎么做才能使可组合对象像本地引用一样工作?

英文:

I created a composable with a reactive boolean. For some reason, the reactive boolean only works with .value in the template v-if. It doesn't automatically unwraps it inside the template.

But if I use a boolean ref directly on the vue component, it works. I reproduced it here

The code:

// useToggle.ts file
import { ref } from &quot;vue&quot;;

const visible = ref(true);

export function useToggle() {
  function toggle() {
    visible.value = !visible.value;
  }

  function close() {
    visible.value = false;
  }

  return {
    visible,
    toggle,
    close,
  };
}


// App.vue file
&lt;script setup lang=&quot;ts&quot;&gt;
import { ref } from &quot;vue&quot;;
import { useToggle } from &quot;./useToggle&quot;;

const visible = ref(true);
const t = useToggle();
&lt;/script&gt;

&lt;template&gt;
  &lt;button @click=&quot;visible = !visible&quot;&gt;toggle local&lt;/button&gt;
  &lt;div v-if=&quot;visible&quot;&gt;local&lt;/div&gt;

  &lt;button @click=&quot;t.toggle&quot;&gt;toggle global without value&lt;/button&gt;
  &lt;div v-if=&quot;t.visible&quot;&gt;global (this doesn&#39;t work)&lt;/div&gt;
  &lt;div v-if=&quot;t.visible.value&quot;&gt;global (this doesn&#39;t work)&lt;/div&gt;

  {{t.visible}} (but this, updates)

&lt;/template&gt;

I don't understand why the v-if doesn't work the same. What can I do to make the composable work like the local ref?

答案1

得分: 1

只有当ref是模板渲染上下文中的顶级属性时才适用解包。如果ref是文本插值的最终评估值,它也会被解包。

https://vuejs.org/guide/essentials/reactivity-fundamentals.html#ref-unwrapping-in-templates

英文:

The unwrapping only applies if the ref is a top-level property on the template render context.
And ref will also be unwrapped if it is the final evaluated value of a text interpolation.

https://vuejs.org/guide/essentials/reactivity-fundamentals.html#ref-unwrapping-in-templates

答案2

得分: 0

<script setup lang="ts">
import { ref } from "vue";
import { useToggle } from "./useToggle";

const visible = ref(true);
const { visible: v, toggle } = useToggle();
</script>

<template>
  <div>composable state: {{ v }}</div>
  <div :style="{ display: 'flex' }">
    <div>
      <button @click="visible = !visible">toggle local</button>
      <div v-if="visible">local</div>
    </div>

    <div>
      <button @click="toggle">toggle global with value</button>
      <div v-if="v">toggle works here</div>
    </div>
    <div>
      <button @click="toggle">toggle global without value</button>
      <div v-if="v">toggle broken here</div>
    </div>
  </div>
</template>
英文:
&lt;script setup lang=&quot;ts&quot;&gt;
import { ref } from &quot;vue&quot;;
import { useToggle } from &quot;./useToggle&quot;;

const visible = ref(true);
const {visible:v,toggle} = useToggle();
&lt;/script&gt;

&lt;template&gt;
  &lt;div&gt;composable state: {{v }}&lt;/div&gt;
  &lt;div :style=&quot;{ display: &#39;flex&#39; }&quot;&gt;
    &lt;div&gt;
      &lt;button @click=&quot;visible = !visible&quot;&gt;toggle local&lt;/button&gt;
      &lt;div v-if=&quot;visible&quot;&gt;local&lt;/div&gt;
    &lt;/div&gt;

    &lt;div&gt;
      &lt;button @click=&quot;toggle&quot;&gt;toggle global with value&lt;/button&gt;
      &lt;div v-if=&quot;v&quot;&gt;toggle works here&lt;/div&gt;
    &lt;/div&gt;
    &lt;div&gt;
      &lt;button @click=&quot;toggle&quot;&gt;toggle global without value&lt;/button&gt;
      &lt;div v-if=&quot;v&quot;&gt;toggle broken here&lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/template&gt;

huangapple
  • 本文由 发表于 2023年6月8日 16:59:39
  • 转载请务必保留本文链接:https://go.coder-hub.com/76430217.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定