【问题标题】:Vue 3 Composition API: Array.length Not ReactiveVue 3 组合 API:Array.length 无反应
【发布时间】:2021-10-05 10:21:43
【问题描述】:

我正在努力弄清楚如何使数组的属性具有反应性。这可能吗?在下面的示例中,filteredResults 数组本身是响应式的,并且可以正常工作,但resultCountRef(包装在reactive() 中)和resultCount 字段都不是响应式的。换句话说,如果我单击Filter for Apples 按钮,filteredResults 将更改为仅一项,但两个计数字段仍保留在3。请注意,在模板中使用 {{filteredResults.length}} 确实可以按预期工作。 Here is a working sample.

这里是代码(一个 Search.vue 组合 API 组件和一个 useFilter 组合函数):

Search.vue:

<template>
  <div>resultCountRef: {{resultCountRef}}</div>
  <div>resultCount: {{resultCount}}</div>
  <div>filteredResults.length: {{filteredResults.length}}</div>
  <div>filteredResults: {{filteredResults}}</div>
  <div>filters: {{filters}}</div>
  <div><button @click="search()">Search</button></div>
  <div><button @click="applyFilter('apples')">Filter for Apples</button></div>
</template>

<script>
import { reactive } from 'vue';
import useFilters from './useFilters.js';

export default {
  setup(props) {
    const products = reactive(['apples', 'oranges', 'grapes']);
    const { filters, applyFilter, filteredResults } = useFilters(products);
    const resultCountRef = reactive(filteredResults.value.length);
    const resultCount = filteredResults.value.length;

    return {
      resultCountRef,
      resultCount,
      filteredResults,
      filters,
      applyFilter,
    };
  },
};
</script>

useFilters.js:

import { ref, onMounted } from 'vue';

function filterResults(products, filters) {
  return products.filter((product) => filters.every(
    (filter) => {
      return product.includes(filter);
    },
  ));
}

export default function useFilters(products) {
  const filters = ref([]);
  const filteredResults = ref([...products]);
  const applyFilter = (filter) => {
    filters.value.push(filter);
    filteredResults.value.splice(0);
    filteredResults.value.splice(0, 0, ...filterResults(products, filters.value));
  };

  return { filters, applyFilter, filteredResults };
}

【问题讨论】:

    标签: vuejs3


    【解决方案1】:

    更新

    const resultCountRef = reactive(filteredResults.value.length);
    

    reactive 不起作用的原因是因为filteredResults.value.length 返回了一个简单的数字并且没有引用任何内容。

    来自@JimCopper 的评论:

    返回的对象只是提供了一个可观察的对象,该对象包装了传入的对象/值/数组(在我的例子中是 filtersResults.length 值)。返回的对象 resultCountRef 是被跟踪的对象,然后可以修改,但这在我的情况下是无用的,这就是为什么反应不起作用。 )


    由于resultCount 依赖于filteredResults,您可以使用computed 来监控变化

    这里是the modified playground

    setup(props) {
        const products = reactive(['apples', 'oranges', 'grapes']);
        const { filters, applyFilter, filteredResults } = useFilters(products);
        // const resultCountRef = reactive(filteredResults.length); 
        const resultCount = computed(() => filteredResults.length) // use computed to react to filteredResults changes
    
        return {
          // resultCountRef,
          resultCount,
          filteredResults,
          filters,
          applyFilter,
        };
    },
    
    

    新文档对计算没有很好的解释,所以我只是从old doc explanation引用它

    计算属性用于以声明方式描述依赖于其他值的值。当您将数据绑定到模板内的计算属性时,当计算属性所依赖的任何值发生更改时,Vue 知道何时更新 DOM。

    【讨论】:

      猜你喜欢
      • 2021-02-11
      • 2021-07-11
      • 2021-10-22
      • 1970-01-01
      • 1970-01-01
      • 2022-01-03
      • 2021-03-15
      • 2021-07-24
      • 1970-01-01
      相关资源
      最近更新 更多