【问题标题】:vue 3 composition api, passing data and making it reactivevue 3 组合 api,传递数据并使其具有反应性
【发布时间】:2022-01-11 10:37:35
【问题描述】:

在我的组件中,我有一个简单的选择菜单,其中包含两个选项(“全部”和“投资”)。这里的想法是从可组合对象中获取一组数据,并在屏幕上显示该数据的每一行。如果我在菜单中选择“全部”,它将显示所有行,如果我选择“投资”,它将过滤数据并仅显示带有 obj.link == “usa”的数据。

一旦我获取数据并将其带入我的组件,如果我 console.log 数据,它就可以正常工作。如果我在过滤后 console.log 数据,我会得到一个空数组。

然后我尝试对组件中的数据进行硬编码并测试过滤器功能,它工作正常。所以错误来自我如何获取我的数据以及我如何尝试使用它。我曾尝试使用不同的钩子,例如 onMounted,但没有成功。

这是我的代码的简约示例。 任何建议或建议都非常受欢迎

从我的数据库中获取数据的组合如下所示:


import {ref} from 'vue'
import { projectFirestore } from '../firebase/config'
import { collection, getDocs } from "firebase/firestore";

const getActorDocs = () => {
    const actorDocs = []
    const error = ref(null)

const loadActors = async () => {
        try {
            const querySnapshot = await getDocs(collection(projectFirestore, "actors"));
            querySnapshot.docs.map(doc => {
                actorDocs.push(doc.data())
            }) 
        } catch (err) {
            error.value = err.message
            console.log(error.value)
        }
    }

    return { actorDocs, error, loadActors} 
}

export default getActorDocs

我的组件:

<template>
    <div class="col-2">
            <span class="lbl">MA</span>
            <select v-model="selectedMA" class="form-select"  >
                <option value="all">all</option>
                <option value="Investment">Investment</option>
            </select>
    </div>

    <p v-for="obj in actorListTest2" :key="obj" :value="obj"> {{obj}} </p>
<template/>


<script >
import {onMounted, onBeforeMount, ref} from 'vue'
import getActorDocs from '../../composables/getActorDocs'
export default {
setup(){

    const selectedMA = ref("Investment")
    const error = ref(null)
    const {actorDocs, loadActors} = getActorDocs()
    var actorListTest1 = actorDocs
    const actorListTest2 = ref([])
    
    loadActors() // loads actors array into actorDocs
    actorListTest2.value = actorListTest1


    console.log(actorListTest1) // <----- prints correctly (see image below)
    if(selectedMA.value === "all"){
      actorListTest2.value = actorListTest1
    }else{
      actorListTest2.value = actorListTest1.filter(obj => {
        return obj.link == selectedMA.value
      })
    }
    
    console.log(actorListTest2.value)  // <----- prints undefined !
    


    return { error, selectedMA, actorListTest2}
    }//setup
}
</script>

这是 console.log(actorListTest1) 的输出:

那么这是console.log(actorListTest2)过滤后的输出:

【问题讨论】:

    标签: vue.js vuejs3 vue-composition-api


    【解决方案1】:

    这是一个known problem with console.log,它不应该用于实时调试对象值。

    actorDocs 不是响应式的,无法与 Vue 中的异步操作一起正常工作。副作用应该在生命周期钩子中完成,例如:mounted

    在当前状态下,getActorDocs 尚未准备好与组合 API 一起使用,因为它受限于遵循承诺控制流以避免这种竞争条件:

    onMounted(async () => {
        await loadActors();
        console.log(actorListTest2.value);
    });
    

    避免这种情况的正确方法是制作actorDocs 反应数组或引用:

    const actorDocs = reactive([]);
    

    如果需要在副作用中访问过滤值,例如console.log,这是在观察者中完成的

    const actorListTest2 = computed(() => actorDocs.filter(...));
    
    watch(actorListTest2, v => console.log(v));   
    
    onMounted(() => {
        loadActors();
    });
    

    【讨论】:

    • 这很好用,谢谢
    猜你喜欢
    • 2021-12-29
    • 2021-02-11
    • 2020-08-05
    • 2021-07-11
    • 2021-12-18
    • 2021-01-14
    • 2021-06-05
    • 2021-06-04
    • 1970-01-01
    相关资源
    最近更新 更多