Phi*_* Li 2 javascript vue.js vuejs3 vue-composition-api
请看下面的代码。
<template>
<div v-for="item in arr" :key="item">{{ item }}</div>
</template>
<script>
import { ref } from "vue";
export default {
name: "TestArr",
setup() {
const arr = [];
arr.push(ref("a"));
arr.push(ref("b"));
arr.push(ref("c"));
return { arr };
}
};
</script>
Run Code Online (Sandbox Code Playgroud)
输出如下
{ "_rawValue": "a", "_shallow": false, "__v_isRef": true, "_value": "a" }
{ "_rawValue": "b", "_shallow": false, "__v_isRef": true, "_value": "b" }
{ "_rawValue": "c", "_shallow": false, "__v_isRef": true, "_value": "c" }
Run Code Online (Sandbox Code Playgroud)
预期产出
a
b
c
Run Code Online (Sandbox Code Playgroud)
我必须在模板中调用 item.value 才能使其工作。这个 sinario for vue3 的解决方法是什么?
干杯!
你做错了; 尝试跟随
setup() {
const arr = ref([]);
arr.value.push("a");
arr.value.push("b");
arr.value.push("c");
return { arr };
}
Run Code Online (Sandbox Code Playgroud)
在普通数组中添加 ref 项是没有意义的。所述阵列应REF。
小智 6
最近,我正在通过开发一个简单的待办事项列表应用程序来学习组合 API。ref()我在使用and处理数组时遇到了一些问题,reactive()发现一些行为可能对学习组合 API 的人有帮助,所以我在这里写下一些话。如果有什么不对的地方请告诉我!
所以......起初一切都按我的预期工作,直到我致力于开发删除功能。
我尝试构建一个按钮,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>
Run Code Online (Sandbox Code Playgroud)
然而,我面临一个关键问题,因为该filter函数不会改变原始值,而是返回一个新值。Vue 无法检测到内部的变化todos。
为了解决这个问题,我重写了我的代码。我没有分配todos给reactive([]),而是用这样的对象扭曲了数组 -> 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>
Run Code Online (Sandbox Code Playgroud)
看来vue只能观察相同引用的变化(JavaScript中的对象是通过引用调用的),但当引用改变时无法检测到变化。因此,我认为“将数组包装在对象内”是在组合 API 中处理数组的更好方法。
根据我们所能找到的最多的信息,我们似乎可以得出一个结论:
ref() 用于原始值和reactive() 值
然而,如果我们编写这样的代码,Vue 仍然能够检测到其中的变化:
const obj = ref({name:"charles"});
return{
...toRefs(obj)
}
Run Code Online (Sandbox Code Playgroud)
原因是当我们将数据传递给 时ref(),它会首先检查发送的数据是原始数据还是对象数据。如果是对象,ref()就会调用reactive()去处理它。换句话说,reactive()是真正在幕后承担工作的人。
到了这个阶段,似乎ref()随时都可以使用。但是,我认为最好使用reactive()对象和ref()基元来产生区别!(如果您对这个主题有任何想法,请分享给我!)