【问题标题】:Data transfer problem between two siblings components (Vue js)两个兄弟组件之间的数据传输问题(Vue js)
【发布时间】:2020-12-07 04:13:01
【问题描述】:

我有三个组件,其中一个是其他组件的父项从LeftBarTalksList 组件,然后TalksList 发出另一个事件并再次监听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);
           });
     }
  }

}

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

谁能帮帮我。

提前致谢。

【问题讨论】:

  • 我认为这是因为您的talk-list 收到了一个prop talk 并且在它更改时也会发出talkAdded,这将导致父级再次更改talk。因此是无限循环。
  • 可能是,我想会是这样,但我想不出另一种解决方案将talk 对象传递给TalkList 组件...有什么想法吗? .

标签: javascript vue.js vue-component vue-props vue-events


【解决方案1】:

我解决了...如此简单,我只需在TalksList 中获取talk 道具的副本,在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);
        }
    }
},

【讨论】:

    猜你喜欢
    • 2019-09-10
    • 1970-01-01
    • 2018-10-03
    • 1970-01-01
    • 2019-12-30
    • 2018-07-27
    • 1970-01-01
    • 1970-01-01
    • 2022-09-28
    相关资源
    最近更新 更多