参考文献 V3中的反应?

看一些 Vue 3的预览教程的例子

我发现了两个例子:

被动反应

<template>
<button @click="increment">
Count is: {{ state.count }}, double is: {{ state.double }}
</button>
</template>


<script>
import { reactive, computed } from 'vue'


export default {
setup() {
const state = reactive({
count: 0,
double: computed(() => state.count * 2)
})


function increment() {
state.count++
}


return {
state,
increment
}
}
}
</script>

裁判

<template>
<div>
<h2 ref="titleRef">{{ formattedMoney }}</h2>
<input v-model="delta" type="number">
<button @click="add">Add</button>
</div>
</template>


<script>
import { ref, computed, onMounted } from "vue";


export default {
setup(props) {
// State
const money = ref(1);
const delta = ref(1);


// Refs
const titleRef = ref(null);


// Computed props
const formattedMoney = computed(() => money.value.toFixed(2));


// Hooks
onMounted(() => {
console.log("titleRef", titleRef.value);
});


// Methods
const add = () => (money.value += Number(delta.value));


return {
delta,
money,
titleRef,
formattedMoney,
add
};
}
};
</script>
71768 次浏览

refreactive之间有一些相似之处,因为它们都提供了一种存储数据的方法,并允许该数据被反应。

然而:

高水平差异:

你不能在原语(字符串,数字,布尔值)上使用反应()-这就是你需要参考的原因,因为你会遇到需要一个“反应布尔值”的情况,例如..。

当然,您可以创建一个对象来包装原始值,并使该对象具有反应性() :

const wrappedBoolean = reactive({
value: true
})

就这样,你改造了一个裁判。

来源: Vue 论坛讨论

被动反应

reactive获取该对象并将反应性 proxy返回给原始对象。

例子

import {ref, reactive} from "vue";


export default {
name: "component",
setup() {
const title = ref("my cool title")
const page = reactive({
contents: "meh?",
number: 1,
ads: [{ source: "google" }],
filteredAds: computed(() => {
return ads.filter(ad => ad.source === "google")
})
})
    

return {
page,
title
}
}
}

解释

在上面的代码中,每当我们想要更改或访问 page的属性时,
page.adspage.filteredAds将通过代理更新。

下面您可以看到我们的示例在上半部分使用 ReactiveReferences,在下面使用其他可选的反应语法。

//reactivity with ref syntax


import { ref, computed } from vue


export default {
setup() {
const capacity = ref(4)
const members = ref(["Tim", "John", "Andr"])
const simpleComputed = computed(() => {
return capacity.value - members.value.length
})


return { capacity, members, simpleComputed }
}
}




//reactivity with reactive syntax


import { reactive, computed } from vue


export default {
setup() {
const event = reactive({
capacity: 4,
members: ["Tim", "John", "Andr"]
simpleComputed: computed(() => {
return event.capacity - event.capacity.length
}
})
return { event }
}
}

如上面底部的代码所示,我创建了一个新的事件常量,它接受一个普通的 JavaScript 对象并返回一个反应对象。在我们的常规组件语法中使用数据选项时,这可能看起来很熟悉,其中我还发送了一个对象。但是,正如您在上面看到的,我还可以将我们的计算属性发送到这个对象中。您还应该注意到,当我使用这种语法时,我们不再需要编写。访问属性时的值。这是因为我只是访问事件对象上的对象属性。您还应该注意到,我们将返回整个事件

这两种语法对于使用都是有效的,并且都不被认为是最佳实践

要点

  • reactive()只接受对象,没有 JS 原语 (字符串,布尔值,数字,BigInt,符号,空,未定义)
  • ref()正在幕后调用 reactive()
  • 因为 reactive()适用于对象,而 ref()调用 reactive(),所以对象对两者都适用
  • 但是,ref()有一个重新分配的 .value属性,reactive()没有这个,因此不能被重新分配

使用

什么时候。

  • 这是原始的 (例如 ABC0、 ABC1、 23等)
  • 这是一个需要稍后重新分配的对象(比如 array-更多信息请点击这里)

什么时候。

  • 它是一个您不需要重新分配的对象,并且您希望避免 ref()的开销

摘要

因为 ref()支持所有的对象类型并且允许使用 .value重新分配,所以看起来是一种可行的方法。ref()是一个很好的起点,但是当您习惯了这个 API,就会知道 reactive()的开销较少,并且您可能会发现它更好地满足了您的需求。

ref()用例

对于原语,您总是使用 ref(),但是对于需要重新分配的对象,比如数组,ref()非常适用。

setup() {
const blogPosts = ref([]);
return { blogPosts };
}
getBlogPosts() {
this.blogPosts.value = await fetchBlogPosts();
}

使用 reactive()执行上述操作将需要重新分配一个属性,而不是整个对象。

setup() {
const blog = reactive({ posts: [] });
return { blog };
}
getBlogPosts() {
this.blog.posts = await fetchBlogPosts();
}

reactive()用例

reactive()的一个很好的用例是属于一起的一组原语:

const person = reactive({
name: 'Albert',
age: 30,
isNinja: true,
});

上面的代码比

const name = ref('Albert');
const age = ref(30);
const isNinja = ref(true);

有用连结

如果你仍然迷路,这个简单的指南帮助了我: https://www.danvega.dev/blog/2020/02/12/vue3-ref-vs-reactive/

一个只使用 ref(): https://dev.to/ycmjason/thought-on-vue-3-composition-api-reactive-considered-harmful-j8c的参数

背后的决策为什么 reactive()ref()存在,因为它们和其他重要的信息,Vue 组合 API RFC: https://vuejs.org/guide/extras/composition-api-faq.html#why-composition-api

Ref/active 两者都用于创建跟踪变更的反应对象。

参考:

它接受一个原语参数并返回一个反应式可变对象。该对象具有单个属性“ value”,并且它将指向该对象获取的参数。

反应:

它接受一个 JavaScript 对象作为参数,并返回该对象的基于代理的反应性副本。

裁判 VS 反应:

通常,ref 和 active 都用于创建反应对象,其中 ref 用于使基本值成为反应对象(Boolean、 Number、 String)。但是,与对象相比,反应不能在原语中工作。

详情请参阅 裁判对反应

参考: 它接受一个原语参数并返回一个反应式可变对象。该对象只有一个属性“ value”,并且它将指向它获取的参数。

反应: 它接受一个 JavaScript 对象作为参数,并返回该对象的一个基于代理的反应性副本。

你可以从这个视频教程中了解更多: Https://www.youtube.com/watch?v=jjm7ychlmu4

我将简单地解释为什么有两种方法可以创建一个反应状态:

其他答案已经显示了两者之间的差异


reactive: 创建一个反应状态。返回对象的反应代理:

import { reactive } from 'vue'


const reactiveObj = reactive({ count: 0 })
reactiveObj.count++

通过选项 API,我们使用 data()保持反应状态。通过使用组合 API,我们可以实现与 reactive API 相同的目标。目前为止,还不错,但是..。

为什么我们需要 ref? ? ?

仅仅因为 reactive有以下限制:

  • 反应性损失:
const state = reactive({ count: 0 })


// the function receives a plain number and
// won't be able to track changes to state.count
callSomeFunction(state.count)
const state = reactive({ count: 0 })
let { count } = state
// does not affect original state
count++
let state = reactive({ count: 0 })


// this won't work!
state = reactive({ count: 1 })
  • 它不能保存字符串、数字或布尔值等基本类型。

因此,ref是由 Vue 提供的,以解决 reactive的局限性。

ref()获取参数并将其包装在具有. value 属性的 ref 对象中返回:

const count = ref(0)


console.log(count) // { value: 0 }
console.log(count.value) // 0


count.value++
console.log(count.value) // 1

裁判可以:

  • 保存任何值类型
  • 被动地替换整个对象:
const objectRef = ref({ count: 0 })


// this works reactively
objectRef.value = { count: 1 }
  • 被传递到函数中或者从普通对象中解构而不失去反应性
const obj = {
foo: ref(1),
bar: ref(2)
}


// the function receives a ref
// it needs to access the value via .value but it
// will retain the reactivity connection
callSomeFunction(obj.foo)


// still reactive
const { foo, bar } = obj

我应该一直使用 ref吗?

个人观点如下

大多数试过这两种方法的开发人员建议使用我读过的文章中的 ref

但就我个人而言,我认为 ref有相同的限制作为 reactive如果不正确使用,你可以很容易陷入“反应性损失”的问题。 ref还有以下一些行为:

  • 在模板中展开,但这只发生在顶级属性中
  • reactive中展开包装
  • 当从数组或类似 Map 的本机集合类型访问引用时,不执行取消包装
  • 参考文献的同步

每次都必须处理 .value也有点令人困惑,Vue 知道这一点,并且在撰写本文时有一个 反应性变换,旨在提供一个解决方案。

我希望您现在对 reactiveref有了更好的理解,但是我认为值得一提的是,还有更多用于反应状态的 API,您应该知道: readonly、 shallowRef、 shallowReactive、 shallowReadonly、 unref 等等。

ref对象接受一个内部值并返回一个反应和可变对象。通常用于基本类型的单个变量,如字符串、布尔值、数字等。

reactive是一个包装器对象,它接受一个对象并返回原始对象的反应代理。通常用于字典结构类型,如 JS 对象。

您可以在本文中了解更多关于参考与反应的内容: Https://dev.to/hirajatamil/must-know-ref-vs-reactive-differences-in-vue-3-composition-api-3bp4