Vue:如何在不失去反应性的情况下合并两个反应性对象

时间:2020-09-28 09:12:18

标签: javascript vue.js vuejs3 vue-composition-api

请考虑以下示例:

const useFeatureX = () => {
  return Vue.reactive({
    x1: 2,
    x2: 3
  });
};

const useFeatureY = () => {
  return Vue.reactive({
    y1: 1,
    y2: 2
  });
};

const App = {
  setup() {
    return { ...useFeatureX(), ...useFeatureY() };
  }
};

Vue.createApp(App).mount("#root");
input {
  max-width: 50px;
}
<script src="https://unpkg.com/vue@next"></script>
<div id="root">
  x1 + x2: <input type="number" v-model="x1"/> + <input type="number" v-model="x2"/> = {{ +x1 + +x2 }} <br/>
  y1 + y2: <input type="number" v-model="y1"/> + <input type="number" v-model="y2"/> = {{ +y1 + +y2 }}
</div>

运行代码段时可以看到,将useFeatureX()useFeatureY()中的两个对象合并到一个{ ...useFeatureX(), ...useFeatureY() }中之后,该应用程序不再跟踪更新。

如何在不失去反应性的情况下合并两个反应性对象?

1 个答案:

答案 0 :(得分:4)

Object destructuring breaks reactivity

当我们想使用大型反应对象的一些属性时,使用ES6解构可能很诱人 获得我们想要的属性:

[...]

不幸的是,这样破坏了两者的反应性 属性将丢失。在这种情况下,我们需要转换 一组引用的反应对象。这些裁判将保留反应 连接到源对象:

相反,您可以使用 toRefs至 “将反应性对象转换为简单对象,其中 结果对象是指向相应属性的ref 原始对象”。

const useFeatureX = () => {
  return Vue.reactive({
    x1: 2,
    x2: 3
  });
};

const useFeatureY = () => {
  return Vue.reactive({
    y1: 1,
    y2: 2
  });
};

const App = {
  setup() {
    return { ...Vue.toRefs(useFeatureX()), ...Vue.toRefs(useFeatureY()) };
  }
};

Vue.createApp(App).mount("#root");
input {
  max-width: 50px;
}
<script src="https://unpkg.com/vue@next"></script>
<div id="root">
  x1 + x2: <input type="number" v-model="x1"/> + <input type="number" v-model="x2"/> = {{ +x1 + +x2 }} <br/>
  y1 + y2: <input type="number" v-model="y1"/> + <input type="number" v-model="y2"/> = {{ +y1 + +y2 }}
</div>