Vue 報錯[Vue warn]: Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders


場景:父組件向子組件傳遞數據,子組件去試圖改變父組件數據的時候。

解決:子組件通過事件向父組件傳遞信息,讓父組件來完成數據的更改。

比如:我的父組件是普通頁面,子組件是彈窗的登錄界面,父組件傳遞的數據(reloginDialog)控制登錄界面的顯示(reloginDialog = true),當登陸成功后,子組件觸發一個事件,父組件捕獲后(reloginDialog = false)將登錄界面隱藏。

父組件調用

<re-login :dialogProp="reloginDialog" @login-success="reloginDialog = $event"></re-login>

子組件詳細【ReLogin.vue】

<template>
    <v-layout row justify-center>
        <v-dialog v-model="dialogProp" persistent max-width="500">
            <v-card class="login-bg">
                <v-card-text>
                    <v-container fluid fill-height>
                        <v-layout align-center justify-center row fill-height text-xs-center>
                            <v-flex xs12>
                                <v-card color="#ffffffe6">
                                    <v-card-title></v-card-title>
                                    <h1 class="headline text-xs-center">****管理系統</h1>
                                    <v-form
                                            ref="form"
                                            lazy-validation
                                    >
                                        <v-flex class="xs8 offset-xs2">
                                            <v-text-field
                                                    color="blue"
                                                    v-model="submitData.empCode"
                                                    label="用戶名"
                                                    :rules="[rules.required]"
                                                    prepend-inner-icon="fas fa-user"
                                            ></v-text-field>
                                        </v-flex>
                                        <v-flex class="xs8 offset-xs2">
                                            <v-text-field
                                                    color="blue"
                                                    v-model="submitData.password"
                                                    prepend-inner-icon="fas fa-lock"
                                                    :append-icon="show1 ? 'fas fa-eye' : 'fas fa-eye-slash'"
                                                    :rules="[rules.required, rules.min]"
                                                    :type="show1 ? 'text' : 'password'"
                                                    label="密碼"
                                                    counter
                                                    @click:append="show1 = !show1"
                                            ></v-text-field>
                                        </v-flex>
                                    </v-form>
                                    <v-flex class="xs8 offset-xs2">
                                        <v-btn color="blue" block dark @click="login">登錄</v-btn>
                                    </v-flex>
                                    <v-card-title></v-card-title>
                                </v-card>
                                <!--頁面提示-->
                                <v-snackbar
                                        v-model="snackbar.show"
                                        multi-line
                                        top
                                        right
                                        :timeout="snackbar.timeout"
                                        color="blue-grey darken-4"
                                >
                                    {{ snackbar.text }}
                                    <v-btn
                                            color="pink"
                                            flat
                                            fab
                                            dark
                                            @click="snackbar.show = false"
                                    >
                                        <v-icon>fas fa-times</v-icon>
                                    </v-btn>
                                </v-snackbar>
                            </v-flex>
                        </v-layout>
                    </v-container>
                </v-card-text>
            </v-card>
        </v-dialog>
    </v-layout>
</template>

<script>
    export default {
        name: "ReLogin",
        props: ['dialogProp'],
        data: () => ({
            // 全局提示
            snackbar: {
                show: false,
                timeout: 6000,
                text: ''
            },
            show1: false,
            submitData:{
                empCode: '',
                password:''
            },
            rules: {
                required: value => !!value || '請填寫此字段.',
                min: v => v.length >= 6 || '最少6個字符'
            }
        }),
        methods: {
            login: function () {
                let me = this;
                let tip = this.snackbar;
                let store = this.$store;
                if (!this.$refs.form.validate()) {
                    tip.show = true;
                    tip.text = '請檢查字段是否符合規則';
                    return;
                }
                store.state.axios.post('/admin/login', this.submitData)
                    .then(function (response) {
                        let data = response.data;
                        if (data.code == 0){
                            sessionStorage.setItem('LOGIN_TOKEN',JSON.stringify(data.data));
                            me.$emit('login-success',false);
                            me.submitData = {
                                empCode: '',
                                password:''
                            };
                        } else{
                            tip.show = true;
                            tip.text = data.msg;
                        }
                    })
                    .catch(function (error) {
                        console.log(error);
                        tip.show = true;
                        tip.text = error;
                    });

            }
        }
    }
</script>

<style scoped>
    .login-bg{
        /*background-image: url("../assets/bg.jpg");*/
        background-image: url("../assets/bg-2.jpeg");
        background-position: center;
        background-size: cover;
    }
</style>

關鍵在於這句話,觸發父組件的事件

me.$emit('login-success',false);

當用戶身份過期需要登錄的時候

登陸成功之后隱藏登錄面板,繼續之前沒完成的操作

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM