首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Vue 3,composition,Array of refs不工作

Vue 3,composition,Array of refs不工作
EN

Stack Overflow用户
提问于 2021-01-18 19:10:37
回答 4查看 5.6K关注 0票数 3

请看下面的代码。

代码语言:javascript
复制
<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>

输出如下所示

代码语言:javascript
复制
{ "_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" }

预期输出

代码语言:javascript
复制
a
b
c

我必须在模板中调用item.value才能使其工作。对于vue3的这个sinario,需要做些什么?

干杯!

EN

回答 4

Stack Overflow用户

发布于 2021-01-18 19:14:17

你做错了,试着跟着做

代码语言:javascript
复制
setup() {
    const arr = ref([]);
    arr.value.push("a");
    arr.value.push("b");
    arr.value.push("c");
    return { arr };
  }

他们没有必要在普通数组中添加ref项。数组应为ref。

票数 10
EN

Stack Overflow用户

发布于 2021-01-18 19:14:30

应该使用value字段访问它们:

代码语言:javascript
复制
  setup() {
    const arr = [];
    arr.push(ref("a").value);
    arr.push(ref("b").value);
    arr.push(ref("c").value);
    return { arr };
  }

但这是一个糟糕的做法,您应该将数组定义为ref,然后将值推送到它:

代码语言:javascript
复制
  setup() {
    const arr = ref([]);
    arr.value.push("a");
    arr.value.push("b");
    arr.value.push("c");
    return { arr };
  }

另一个精心设计的解决方案是使用该值初始化数组:

代码语言:javascript
复制
  setup() {
    const arr = ref(["a","b","c"]);
   
    return { arr };
  }
票数 1
EN

Stack Overflow用户

发布于 2021-12-29 09:26:06

一些关于将array与ref()和reactive()一起使用的信息可能会有所帮助。

最近,我正在通过开发一个简单的待办事项列表应用程序来学习组合API。我在使用ref()reactive()处理数组时遇到了一些问题,发现了一些可能对正在学习组合API的人有帮助的行为,所以我在这里写下了一些单词。如果有什么问题,请告诉我!

1.使用reactive()处理数组有什么问题?

首先,在我开始开发So...at函数之前,一切都像我所期望的那样工作。

我试图建立一个按钮,当它被点击时,它将触发deleteHandler函数。deleteHandler会过滤掉todos中的元素

下面是我的代码:

代码语言:javascript
复制
<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:[]})对象扭曲了数组。而且它起作用了!

代码语言:javascript
复制
<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()?

根据我们能找到的最多的信息,我们似乎可以得出一个结论:

原始值和反应值的

ref()

然而,如果我们像这样写一些代码,Vue仍然能够检测到它内部的变化:

代码语言:javascript
复制
const obj = ref({name:"charles"});

return{
 ...toRefs(obj)
}

原因是,当我们将数据传递给ref()时,它会首先检查发送的数据是原始数据还是对象数据。如果是object,ref()会调用reactive()来处理it.In,换句话说,reactive()才是真正负责幕后工作的人。

小结论

在这个阶段,我们似乎可以随时使用ref()。但是,我认为对于object使用reactive(),对于原语使用ref()会更好!(如果您对这个主题有任何想法,请与我分享!)

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65773395

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档