如何在不失去反应性的情况下展平计算对象
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
编辑
我考虑过的备选方案:
- 直接在模板中使用对象数据
- 使用每个属性的计算 属性
但这些是备选方案,并非我真正希望的那样。
您可以使用带有 toRef
的 reactive
对象。
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>
虽然,这对我来说有点尴尬。如果可能的话,我会使用其他方法;为什么 plus1
和 plus2
需要成为同一对象的一部分?怎么了
const counter = ref(0);
const plus1 = computed(() => counter.value + 1);
const plus2 = computed(() => counter.value + 2);
这个?我相信你的真实例子要复杂得多,但它可能值得考虑:computed
是在这里使用的直观的东西,在单个变量上。
您不能直接展平计算对象(目前没有 API 提供这样做)。
我最终求助于直接在模板中使用计算对象。
我正在使用计算对象。我想在设置函数中公开该对象的属性,但我还没有找到方法。
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
编辑
我考虑过的备选方案:
- 直接在模板中使用对象数据
- 使用每个属性的计算 属性
但这些是备选方案,并非我真正希望的那样。
您可以使用带有 toRef
的 reactive
对象。
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>
虽然,这对我来说有点尴尬。如果可能的话,我会使用其他方法;为什么 plus1
和 plus2
需要成为同一对象的一部分?怎么了
const counter = ref(0);
const plus1 = computed(() => counter.value + 1);
const plus2 = computed(() => counter.value + 2);
这个?我相信你的真实例子要复杂得多,但它可能值得考虑:computed
是在这里使用的直观的东西,在单个变量上。
您不能直接展平计算对象(目前没有 API 提供这样做)。
我最终求助于直接在模板中使用计算对象。