首页 > 解决方案 > 局部变量在 eventBus.emit 之后更新

问题描述

我想不出更好的标题,我会试着简要解释一下并提供我的例子。

我使用 Vuetify 作为框架,并v-text-fieldtemplate. 这以前没有发生过,只发生在这个特定的组件中。

所以,我得到了 的值v-model并使用eventBus.emit. 现在,在 之后emit,我将值重置为 null。但是,这样做会更新发送的数据,emit这很奇怪。在取消它们后,我不会再次重新发送它们。

我正在检查使用console.log(payload),数据是正确的!在v-dialogis之后false,这个发送的数据会自动失效。这根本不应该发生。

模板:

<template>
<v-dialog v-model="dialog" scrollable width="500">
    <v-card>
        <v-card-title primary-title class="title" primary-title>
            Add</v-card-title>
        <v-divider class="menu_divider_no_margin"></v-divider>
        <v-card-text>
            <v-container fill-height grid-list-lg>
                <v-form ref="form" v-model="valid" lazy-validation>
                    <v-layout wrap row fill-height>

                        <v-flex xs6>
                            <v-text-field v-model="season_payload.season.title" label="Title"></v-text-field>
                        </v-flex>

                        <v-flex xs6>
                            <v-text-field v-model="season_payload.season.number" label="Number" type="number" :rules="rules.generic" required></v-text-field>
                        </v-flex>


                    </v-layout>
                </v-form>
            </v-container>
        </v-card-text>
        <v-divider class="menu_divider_no_margin"></v-divider>

        <v-card-actions class="v-card-actions-custom-rtl">
            <v-btn flat @click.prevent="dialog = false">Close</v-btn>
            <v-btn flat @click.prevent="addItem">Add</v-btn>
        </v-card-actions>

    </v-card>
</v-dialog>
</template>

脚本:

<script>
export default {
    data() {
        return {
            constants: constants,
            valid: false,
            dialog: false,
            item_payload: {
                create: true
            },
            rules: {
                generic: [v => !!v || 'Required!']
            },
            season_payload: {
                season: {
                    number: null,
                    title: null
                }
            }
        }
    },
    beforeDestroy() {
        this.$eventBus.$off('test_compo')
    },
    watch: {
        dialog(newValue) {
            if (!newValue) {
                this.item_payload.create = true

                this.season_payload.season.number = null
                this.season_payload.season.title = null

                this.$refs.form.resetValidation()
            }
        }
    },
    mounted() {
        let app = this
        app.$eventBus.$on('test_compo', (payload) => {

            app.dialog = true
        });
    },
    methods: {
        addItem() {
            let app = this
            let payload = {
                season: app.season_payload.season,
                create: app.item_payload.create
            }


            app.$eventBus.$emit("reference", payload)
            app.dialog = false
        }
    }
}
</script>

标签: javascriptvue.jsvuejs2

解决方案


这只是改变引用类型的问题。

让我们从这里开始:

let payload = {
    season: app.season_payload.season,
    create: app.item_payload.create
}

app只是this当前组件的别名。

app.season_payload.season是一个对象。新创建的payload对象具有season指向同一对象的属性。它不是一个副本,它是同一个对象。

然后我们有这个:

this.season_payload.season.number = null
this.season_payload.season.title = null

这是更新对象的numbertitle属性this.season_payload.season。这与我们在前面的代码中看到的对象相同。它是同一个对象,因此在此处更改它也会影响使用它的其他任何地方。

任何拥有同一个season对象的东西都会被清空。毕竟,它是同一个对象。

为避免这种情况,您需要在沿线某处创建一个新对象。有几个机会可以做到这一点。例如,我们可以像这样创建有效负载:

let payload = {
    season: {
        number: app.season_payload.season.number,
        title: app.season_payload.season.title
    },
    create: app.item_payload.create
}

或者:

let payload = {
    season: {...app.season_payload.season},
    create: app.item_payload.create
}

作为numbertitle都是原语,没有持久的链接到app.season_payload.season.

或者,我们可以用不同的方式编写清零:

this.season_payload.season = {
    number: null,
    title: null
}

推荐阅读