有关使用数组与 ref() 和 reactive() 的一些信息可能会有所帮助。
最近,我正在通过开发一个简单的待办事项列表应用程序来学习作文 API。我在使用ref() 和reactive() 处理数组时遇到了一些问题,发现一些行为可能对正在学习组合API 的人也有帮助,所以我在这里写了一些话。如果有什么问题,请告诉我!
1。使用reactive()处理数组有什么问题?
所以...起初一切都按我的预期工作,直到我开始开发删除功能。
我尝试构建一个按钮,当它被点击时会触发deleteHandler 函数。而deleteHandler 会过滤掉todos 中的元素:
这是我的代码:
<template>
<div>
<h1>reactive</h1>
<button @click="add">click</button>
<div v-for="item in todos" :key="item">
<button @click="mark(item)">mark</button>
<span>{{item}}</span>
<button @click="deleteHandler(item.id)">delete</button>
</div>
</div>
</template>
<script>
import {reactive, ref} from "vue";
export default {
name: "ReactiveMethod",
setup(){
let todos = reactive([])
const id = ref(0);
function add(){
todos.push({id:id.value, name:"hallo", state:"undone"});
id.value += 1
}
function mark(item){
if(item.state === "undone"){
item.state = "done"
}else{
item.state = "undone"
}
}
function deleteHandler(id){
const temp = todos.filter((element)=>{
return element.id !== id
})
todos = temp
}
return {
todos,
id,
deleteHandler,
add,
mark
}
}
}
</script>
但是,我面临一个关键问题,因为 filter 函数不会改变原始值,而是返回一个新值。 Vue 无法检测到 todos 内部的变化。
为了解决这个问题,我重写了我的代码。我没有将todos 分配给reactice([]),而是使用这样的对象-> reactive({todos:[]}) 扭曲了数组。它有效!
<template>
<div>
<h1>reactive</h1>
<button @click="add">click</button>
<div v-for="item in todos" :key="item">
<button @click="mark(item)">mark</button>
<span>{{item}}</span>
<button @click="deleteHandler(item.id)">delete</button>
</div>
</div>
</template>
<script>
import {reactive, ref, toRefs} from "vue";
export default {
name: "ReactiveMethod",
setup(){
const state = reactive({
todos:[]
})
const id = ref(0);
function add(){
state.todos.push({id:id.value, name:"hallo", state:"undone"});
id.value += 1
}
function mark(item){
if(item.state === "undone"){
item.state = "done"
}else{
item.state = "undone"
}
}
function deleteHandler(id){
const temp = state.todos.filter((element)=>{
return element.id !== id
})
state.todos = temp
}
return {
...toRefs(state),
id,
deleteHandler,
add,
mark
}
}
}
</script>
结论
vue 似乎只能在引用相同的情况下观察变化(JavaScript 中的对象是通过引用调用的),但在引用发生变化时无法检测到变化。作为结果,我认为“将数组包装在对象中”是在组合 API 中处理数组的更好方法。
2。 ref() 用于原始值和 reactive() 值?
根据我们所能找到的最多的信息,似乎可以得出一个结论:
ref() 用于原始值和 reactive() 值
但是,如果我们这样写一些代码,Vue 仍然能够检测到其中的变化:
const obj = ref({name:"charles"});
return{
...toRefs(obj)
}
原因是当我们向ref()传递数据时,它会首先检查发送的数据是原始数据还是对象数据。如果是对象,ref() 会调用reactive() 处理它。也就是说,reactive() 是真正在幕后工作的人。
小结论
现阶段,我们似乎可以随时使用ref()。但是,我认为最好将reactive() 用于对象,将ref() 用于原语以产生影响!(如果您对此主题有任何想法,请分享给我!)