在异步v-for

时间:2017-09-30 03:26:01

标签: vue.js vuejs2

我有一个项目列表,直到异步调用发生后才会创建。我需要能够获得第一个(或任何)创建项的getBoundingClientRect()。

以此代码为例:

<template>
    <div v-if="loaded">
        <div ref="myItems">
            <div v-for="item in items">
                <div>{{ item.name }}</div>
            </div>
        </div>
    </div>
    <div v-else>
        Loading...
    </div>
</template>

<script>
    import axios from 'axios';

    export default {
        data() {
            return {
                items: []
            }
        },
        created() {
            axios.get('/url/with/some/data.json').then((response) => {
                this.items = response.data;
                this.loaded = true;
            }, (error) => {
                console.log('unable to load items');
            });
        },
        mounted() {
            // $refs is empty here
            console.log(this.$refs);

            // this.$refs.myItems is undefined
        }
    };
</script>

所以,我正在尝试使用myItems方法访问mounted()参考,但此时this.$refs为空{}。因此,我尝试使用组件watch以及各种其他方法来确定何时可以读取ref值,但是未成功。

任何人都能引导我朝着正确的方向前进吗?

一如既往,再次感谢!!

更新

this.$watch方法中添加了mounted()$refs仍然以{}的形式返回。然后我将updated()方法添加到代码中,然后能够在那里访问$refs并且它似乎有效。但是,我不知道这是否是正确的解决方案?

vuejs通常如何处理基于异步数据动态移动div到屏幕上位置的内容?这类似于我正在尝试做的事情,一旦首先渲染它就在屏幕上抓取一个元素(如果它甚至应该根据异步数据进行渲染),然后访问它以对它做一些事情(移动它)到一个位置)?

2 个答案:

答案 0 :(得分:0)

您可以在axios promise返回响应后执行此操作,而不是在安装期间执行this.$refs.myItems

您还要更新itemsloaded,如果您想使用手表,可以使用那些

答案 1 :(得分:0)

晚一点,也许对某人有帮助。

问题是,您正在使用v-if,这意味着带有ref="myItems"的元素尚不存在。在您的代码中,仅当Axios解析this.loaded时才会发生这种情况。

更好的方法是使用v-show

<template>
<div>
    <div v-show="loaded">
        <div ref="myItems">
            <div v-if="loaded">
            <div v-for="item in items">
                <div>{{ item.name }}</div>
            </div>
            </div>
        </div>
    </div>
    <div v-show="!loaded">
        Loading...
    </div>
</div>
</template>
  

区别在于带有v-show的元素将始终被渲染并保留在DOM中; v-show仅切换元素的display CSS属性。

https://vuejs.org/v2/guide/conditional.html#v-show