在eventBus.emit之后更新局部变量

时间:2019-07-17 20:21:20

标签: javascript vue.js vuejs2

我想不出更好的标题,我将尝试简要地解释一下并提供示例。

我使用Vuetify作为框架,并向v-text-field添加了一些template。这以前没有发生过,仅发生在此特定组件中。

因此,我正在获取v-model的值,并使用eventBus.emit发送它们。现在,在emit之后,我将值重置为null。但是,这样做会通过emit更新发送的数据,这很奇怪。使它们无效后,我不再重新发送它们。

我正在使用console.log(payload)进行检查,数据正确! v-dialogfalse之后,此发送的数据将自动无效。这根本不应该发生。

模板:

<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>

1 个答案:

答案 0 :(得分:1)

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

让我们从这里开始

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

这将更新对象number的{​​{1}}和title属性。这与我们在前面的代码中看到的对象相同。这是同一对象,因此在此处更改它也会影响使用它的其他任何地方。

拥有相同的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 } number都是基元,因此没有持久的链接到title

或者我们可以用不同的方式写出空值:

app.season_payload.season