【问题标题】:Can I use watch from Vue 3 with primitives?我可以将 Vue 3 中的 watch 与原语一起使用吗?
【发布时间】:2023-01-07 19:57:41
【问题描述】:

每次获取数据时,我都想更改布尔值以呈现 <Loading /> 组件。 我不希望我的条件取决于数组长度。所以我决定这样做。 并且 <Loading /> 组件从不对 state.isLoading 更改做出反应。 我尝试使用 watch 来测试 this.isLoading 是否发生了变化。但是watch 从来没有记录过任何东西。 我从未见过有人使用带有原语的手表。 问题是我不知道我是否可以将 watch 与基元一起使用以及我可以使用什么来代替,比如 React 中的 useEffect

App.vue

<script setup>
  import { RouterView } from 'vue-router'
  import { watch, ref, onMounted, reactive } from 'vue';
  import Navbar from './components/Navbar.vue'
  import { useShopStore } from './stores/shopStore';

  const shop = useShopStore()

  const bool = ref(shop.isLoading)

  console.log(bool)

  watch(bool.value, (newBool) => {
    console.log(newBool)
  }, { deep: true })
</script>

类别.vue

<template>
  <LoadingVue v-if="shop.isLoading" />
  <div v-else class="category__menu">
    <CardVue
      v-for="item in shop.category"
      :item="item"
      :key="item.id"
    />
  </div>
</template>

ShopStore.js

actions: {
  async getProducts(path) {
    if (typeof path !== 'string' || path === undefined) return
    this.setLoading()
    try {
      const response = fetch(`https://fakestoreapi.com/products/category/${path}`)
      .then(res => res.json())
      .then(res => this.category = res)
    } catch (error) {
      console.log(error)
      alert('Something went wrong')
    }
    this.setLoading()
  },
  setLoading() {
    console.log('setLoading')
    this.isLoading = !this.isLoading
  }
}

【问题讨论】:

  • 您可以使用手表任何 被动的数据,表示通过ref(...)reactive(...) 函数调用创建的数据(前者用于原语)。所以,不,你不能看一个“裸”基元,但你应该能够将它与包装基元一起使用,就像你正在做的那样,尽管你不应该在手表中使用bool.value。应该只是bool,不是吗?
  • @HovercraftFullOfEels Full Of Eels 为什么它在布尔值更改时从不记录?
  • 同样,watch(bool.value, (newBool) =&gt; { 不应该是watch(bool, (newBool) =&gt; { 吗?您正在观察的是反应值,而不是裸值。
  • @HovercraftFullOfEels 试过了,没有任何改变。函数,改变值运行,但 watch 不做任何事情。
  • @HovercraftFullOfEels 如果我将 bool 分配给对象 shop,它会起作用:watch(bool, (newBool) =&gt; { console.log(newBool.isLoading) }, { deep: true })

标签: vue.js vuejs2 vue-component vuejs3


【解决方案1】:

您正在对反应数据创建一个新的引用。这就像按值复制,原始反应数据和包裹在它上面的新引用没有连接。因此,当 shop.isLoading 更改时,您的 bool ref 不会更改,它们现在是两个不同的变量。

我猜你在商店里用的是 pinia。如果是这样,shop.isLoading 已经是反应式的,您不必将其包装到 ref 中。

<Loading v-model="shop.isLoading" />

您还可以使用来自 pinia 的 storeToRefs 辅助方法对您的商店使用解构并获取您的状态的引用:

const { isLoading } = storeToRefs(shop)

console.log(isLoading.value)

【讨论】:

  • 我在描述中添加了额外的代码,这样你就会明白我想做什么。这是条件渲染。我知道我可以在 v-model 中使用 shop.IsLoading 但我的应用程序的逻辑有点不同。我真的很想知道如何检测 Vue 中的变化,就像我在 React 中使用 useEffect 所做的那样。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-09-09
  • 2019-05-23
  • 2015-09-21
  • 2016-01-02
  • 2015-12-02
  • 1970-01-01
相关资源
最近更新 更多