1

我有三个组件,其中一个是其他组件的父级,我试图传递一个talk在兄弟姐妹之间调用的对象,在事件中从FollowedBrowserto发出它LeftBar,然后通过 prop 从LeftBarTalksList组件传递它,之后另一个事件由TalksListand发出又听了一次LeftBar,最后这个组件将talk对象重新定义为一个空对象。

这是我的父组件LeftBar

<template>
    <v-navigation-drawer width="25%" permanent clipped app light>
        <talks-list v-if="inRoute('messages')" :talk="talk" @talkAdded="talkAdded()"/>
        <template v-if="inRoute('messages')" v-slot:prepend>
            <followed-browser @newTalk="addTalk($event)"/>
        </template>
    </v-navigation-drawer>
</template>

<script>
    import FollowedBrowser from "./FollowedBrowser";
    import TalksList from "./TalksList";
    import { mapGetters } from "vuex";
    export default {
        data(){
            return {
                talk: {}
            }
        },
        components: {
            FollowedBrowser,
            TalksList
        },
        methods: {
            addTalk(talk){
                this.talk = talk;
            },
            talkAdded(){
                this.talk = {};
            }
        }
    }
</script>

这是我的两个孩子:

TalksList.vue

<template>
    <v-container class="my-0 px-5">

        <v-list flat>
            <v-list-item-group class="my-0">
                <div class="ma-0 pa-0" v-for="(talk, index) in talks" :key="index">
                    <v-divider v-if="talk.divider"></v-divider>
                    <v-list-item v-else class="px-2" style="cursor: pointer">
                        <template>

                            <v-list-item-avatar>
                                <v-img :src="correctedImageUrl(talk.recipient)"></v-img>
                            </v-list-item-avatar>

                            <v-list-item-content>
                                <v-list-item-title>
                                    <span class="blue--text text--lighten-1">{{ completeName(talk.recipient) }}</span>
                                </v-list-item-title>
                                <v-list-item-subtitle>
                                    <span>{{ talk.recipient.username }}</span>
                                </v-list-item-subtitle>
                            </v-list-item-content>

                        </template>
                    </v-list-item>

                </div>
            </v-list-item-group>
        </v-list>
    </v-container>

</template>

<script>
    import axios from "axios";
    export default {
        data(){
            return {
                talks: []
            }
        },
        props: {
            talk: {
                type: Object,
                default: null,
                required: true
            }
        },
        watch: {
            talk(val){
                if(val){
                    this.talks.splice(0, 1, val);
                    this.$emit("talkAdded");
                }
            }
        }
    }
</script>

FollowedBrowsed.vue

<template>
    <div style="display: inline">
        <v-dialog scrollable v-model="dialog" max-width="400px" max-height="500px">

            <v-card :loading="loading">
                <v-text-field dense outlined color="blue lighten-1" label="Nombre de usuario" class="px-5" append-icon="mdi-magnify" v-model="browsedUsername"/>
                <v-divider></v-divider>
                <v-card-text style="height: 300px;" class="px-2">
                    <v-list>
                        <v-list-item class="px-2" style="cursor: pointer" v-for="listUser in filteredFollowed" :key="listUser.id" @click.prevent="newTalk(listUser)">
                            <v-list-item-content>
                                <v-list-item-title>
                                    <span class="blue--text text--lighten-1">{{ completeName(listUser) }}</span>
                                </v-list-item-title>
                                    <v-list-item-subtitle>
                                        <span>{{ listUser.username }}</span>
                                </v-list-item-subtitle>
                            </v-list-item-content>
                        </v-list-item>
                    </v-list>
                </v-card-text>
            </v-card>
        </v-dialog>
    </div>
</template>

<script>
    import { mapGetters } from "vuex";
    import axios from "axios";
    export default {
    data(){
        return {
            browsedUsername: "",
            loading: false,
            dialog: false,
            skeleton: true,
            followed: []
        }
    },
    watch: {
        dialog(dialog){
            if(!dialog){
                this.browsedUsername = "";
                this.item = null;
            }
        }
    },
    computed: {
        ...mapGetters({
            authenticated: "auth/authenticated",
            user: "auth/user"
        }),
        filteredFollowed(){
            return this.followed.filter((user) => {
                return user.username.toLowerCase().indexOf(this.browsedUsername.toLowerCase()) !== -1;
            })
        }
    },
    mounted(){
        axios.get("all_followers_followed/followed")
            .then((response) => {
                if(response.data){
                    this.followed = response.data;
                    this.skeleton = false;
                }
            })
            .catch((error) => {
                console.log(error)
            });
  },

  methods: {
     async newTalk(user){
        this.loading = "blue lighten-1";
        await axios.post("messages/new_talk", {recipient_id: user.id})
           .then((response) => {
              if(response.data){
                 this.dialog = false;
                 this.$emit("newTalk", {
                    messages_number: 0,
                    recipient: user,
                    sender: this.user
                 });
              }
           })
           .catch((error) => {
              console.log(error);
           });
     }
  }

}

当在组件newTalk内部调用该方法时,会发出事件,但之后我的屏幕冻结,就像应用程序在无限循环中一样,我不知道为什么。我省略了一些我认为不相关的代码。FollowedBrowsernewTalk

有谁能够帮我。

提前致谢。

4

1 回答 1

0

我解决了...很简单,我只需要在里面获取一个talkprop的副本TalksList,里面watch放这个:

watch: {
    talk(val){

        if(val){

            if(this.talks.length){
                this.talks.unshift({ divider: true });
            }

            let buffer = new Object();
            let talk = new Object();

            buffer.data = val;
            talk = buffer.data;

            this.talks.unshift(talk);
        }
    }
},
于 2020-08-18T04:28:21.607 回答