如何在不失去反应性的情况下展平计算对象

How to flatten a computed object without losing reactivity

我正在使用计算对象。我想在设置函数中公开该对象的属性,但我还没有找到方法。

export default {
  setup() {
    const counter = Vue.ref(0)
    const data = Vue.computed(() => ({
      plus1: counter.value + 1,
      plus2: counter.value + 2,
    }))
    const increment = () => {
      counter.value++
    }
    
    return {
      counter,
      plus1: data.value.plus1, // This is bad, no reactivity
      plus2: data.value.plus2,
      increment
    }
  },
};

全码笔在此:https://codepen.io/philfontaine/pen/KKmzJrK

编辑

我考虑过的备选方案:

但这些是备选方案,并非我真正希望的那样。

您可以使用带有 toRefreactive 对象。

Vue.createApp({
  setup() {
    const counter = Vue.ref(0);

    const data = Vue.reactive({
      get plus1() { return counter.value + 1; },
      get plus2() { return counter.value + 2; },
    });

    const increment = () => counter.value++;

    return {
      counter,
      plus1: Vue.toRef(data, 'plus1'),
      plus2: Vue.toRef(data, 'plus2'),
      increment
    }
  }
}).mount('#app');
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}

a, button {
  color: #4fc08d;
}

button {
  background: none;
  border: solid 1px;
  border-radius: 2em;
  font: inherit;
  padding: 0.75em 2em;
  margin: 0.85em;
}
<script src="https://unpkg.com/vue@next"></script>

<div id="app">
  <div>{{ counter }}</div>
  <div>{{ plus1 }}</div>
  <div>{{ plus2 }}</div>
  <button @click="increment">Increment</button>
</div>

虽然,这对我来说有点尴尬。如果可能的话,我会使用其他方法;为什么 plus1plus2 需要成为同一对象的一部分?怎么了

const counter = ref(0);
const plus1 = computed(() => counter.value + 1);
const plus2 = computed(() => counter.value + 2);

这个?我相信你的真实例子要复杂得多,但它可能值得考虑:computed 是在这里使用的直观的东西,在单个变量上。

您不能直接展平计算对象(目前没有 API 提供这样做)。

我最终求助于直接在模板中使用计算对象。