在Vuejs中从Cloud Firestore提取数据时如何显示微调框?

时间:2019-02-25 15:04:11

标签: firebase vue.js google-cloud-firestore

我也在使用vuex开发Firebase和vuejs。所以在onauthStateChanged()方法中,我尝试获取所有数据形式的帖子集合。它需要一些时间才能显示,与此同时,我想显示微调器,该微调器指定用户正在加载某些内容。

我尝试过并且它的工作很酷,但是代码的问题是

  <loadingSpinner v-if="loading"></loadingSpinner>
                <div v-if="posts.length">
                    <div v-for="post in posts" v-bind:key=post.id class="post">
                        <h5>{{ post.userName }}</h5>
                        <span>{{ post.createdOn | formatDate }}</span>
                        <p>{{ post.content | trimLength }}</p>
                        <ul>
                            <li><a @click="openCommentModal(post)">comments {{ post.comments }}</a></li>
                            <li><a @click="likePost(post.id, post.likes)">likes {{ post.likes }}</a></li>
                            <li><a @click="viewPost(post)">view full post</a></li>
                        </ul>
                    </div>
                </div>
                <div v-else>
                    <p class="no-results">There are currently no posts</p>
                </div>

负责旋转动画的旋转程序组件:

<loadingSpinner v-if="loading"></loadingSpinner>

以下html代码用于显示Firebase中的数据

发布和加载变量是根据vuex状态计算得出的属性

问题是重新加载页面时,微调器沿

显示
<div v-else>
     <p class="no-results">There are currently no posts</p>
</div>

我想在加载微调框时限制v-else条件。

顺便说一句,加载的计算属性是一个基于onAuthstateChanged()Firebase方法做出反应的布尔值

这是我的整个vuex存储文件:

    import Vue from 'vue'
import Vuex from 'vuex'
const fb = require('./firebaseConfig.js')

Vue.use(Vuex)

// handle page reload
fb.auth.onAuthStateChanged(user => {
    if (user) {
        store.commit('setCurrentUser', user)
        store.dispatch('fetchUserProfile')

        fb.usersCollection.doc(user.uid).onSnapshot(doc => {
            store.commit('setUserProfile', doc.data())
        })

        // realtime updates from our posts collection
        fb.postsCollection.orderBy('createdOn', 'desc').onSnapshot(querySnapshot => {
            // check if created by currentUser
            let createdByCurrentUser
            if (querySnapshot.docs.length) {
                createdByCurrentUser = store.state.currentUser.uid == querySnapshot.docChanges[0].doc.data().userId ? true : false
            }

            // add new posts to hiddenPosts array after initial load
            if (querySnapshot.docChanges.length !== querySnapshot.docs.length
                && querySnapshot.docChanges[0].type == 'added' && !createdByCurrentUser) {

                let post = querySnapshot.docChanges[0].doc.data()
                post.id = querySnapshot.docChanges[0].doc.id

                store.commit('setHiddenPosts', post)
            } else {
                store.commit('setLoading', true)
                let postsArray = []
                querySnapshot.forEach(doc => {
                    let post = doc.data()
                    post.id = doc.id
                    postsArray.push(post)
                })     
                store.commit('setPosts', postsArray)
                store.commit('setLoading', false)
            }
        })
    }
})

export const store = new Vuex.Store({
    state: {
        currentUser: null,
        userProfile: {},
        posts: [],
        hiddenPosts: [],
        loading: true
    },
    actions: {
        clearData({ commit }) {
            commit('setCurrentUser', null)
            commit('setUserProfile', {})
            commit('setPosts', null)
            commit('setHiddenPosts', null)
        },
        fetchUserProfile({ commit, state }) {
            fb.usersCollection.doc(state.currentUser.uid).get().then(res => {
                commit('setUserProfile', res.data())
            }).catch(err => {
                console.log(err)
            })
        },
        updateProfile({ commit, state }, data) {
            let name = data.name
            let title = data.title

            fb.usersCollection.doc(state.currentUser.uid).update({ name, title }).then(user => {
                // update all posts by user to reflect new name
                fb.postsCollection.where('userId', '==', state.currentUser.uid).get().then(docs => {
                    docs.forEach(doc => {
                        fb.postsCollection.doc(doc.id).update({
                            userName: name
                        })
                    })
                })
                // update all comments by user to reflect new name
                fb.commentsCollection.where('userId', '==', state.currentUser.uid).get().then(docs => {
                    docs.forEach(doc => {
                        fb.commentsCollection.doc(doc.id).update({
                            userName: name
                        })
                    })
                })
            }).catch(err => {
                console.log(err)
            })
        }
    },
    mutations: {
        setLoading(state, payload){
            state.loading = payload
        },
        setCurrentUser(state, val) {
            state.currentUser = val
            // console.log(val)
        },
        setUserProfile(state, val) {
            state.userProfile = val
            // console.log(val)
        },
        setPosts(state, val) {
            if (val) {
                state.posts = val
            } else {
                state.posts = []
            }
        },
        setHiddenPosts(state, val) {
            if (val) {
                // make sure not to add duplicates
                if (!state.hiddenPosts.some(x => x.id === val.id)) {
                    state.hiddenPosts.unshift(val)
                }
            } else {
                state.hiddenPosts = []
            }
        }
    },
})

有什么建议吗?

1 个答案:

答案 0 :(得分:0)

我会微调您的v-if/v-else逻辑。

<loadingSpinner v-if="loading" />
<div v-else-if="posts.length"></div>
<div v-else>
    <p class="no-results">There are currently no posts</p>
</div>

差异是v-else-if上的posts.length,而不是v-if。这样,就有3个不同的状态。

  1. 正在加载,显示微调器。
  2. 未加载,显示帖子。
  3. 未加载,没有帖子,没有结果。