dttnb997315 2019-05-10 20:11
浏览 233

如何使用vuex将子组件中的数据和函数用于另一个组件?

I have to create a supervisor object that is made by 2 foreign key, those foreign key are user_id (so it has user fields) + program_id( a program in the college). To do it well, i have to use 2 components. First will have all user fields for user registration. Second, will have the program for supervisor. The parent component will be the supervisor, in that component i want to use the user component. By this way, i want to use the fields data from user component and use them into supervisor component when i will press on the create button that will send all the data from (user_id create from the user component, supervisor_program added from a pick list) and send by axios to my api route.

supervisor form file

<template>
    <div>
        <md-card class="md-layout-item md-size-100 md-small-size-100">
            <md-card-header>
                <div class="md-title">Inscription d'un superviseur</div>
            </md-card-header>
            <inscription-view :user="user"></inscription-view>
            <md-card-content>
                <div class="md-layout md-gutter">
                    <div class="md-layout-item md-small-size-100">
                        <md-field :class="getValidationProgramClass('programme')">
                            <label for="programme">Programme</label>
                                <md-select v-model="superviseur.programme.id" name="programme" id="programme" :disabled="sending">
                                <md-option value="" disabled>Choisissez un programme...</md-option>
                                <md-option v-for="p in programmes" :key="p.id" :value="p.id">
                                    {{ p.nom }}
                                </md-option>    
                            </md-select>
                            <span class="md-error" v-if="!$v.superviseur.programme.required">Le champ 'programme' est requis</span>
                        </md-field>
                    </div>
                </div>
            </md-card-content>
            <md-card-actions>
                <md-button @click="cancel()" class="md-raised md-accent">Annuler</md-button>
                <md-button @click.prevent="validaterChamps()" class="md-raised md-primary" :disabled="sending">Créer</md-button>
            </md-card-actions>

            <md-progress-bar md-mode="indeterminate" v-if="sending" />
        </md-card>
    </div>
</template>

<script>
    import lodash from 'lodash'
    import axios from 'axios'
    import VueMaterial from 'vue-material'
    import { validationMixin } from 'vuelidate'
    import { required, minLength, maxLength, between, sameAs } from 'vuelidate/lib/validators'
    import inscription from '../utilisateur/Inscription.vue'

    export default {
        middleware: 'auth',
        components:{ VueMaterial, validationMixin, 'inscription-view': inscription },
        mixins: [validationMixin],
        name: 'SuperviseurFormulaire',

        data: () => ({
            programmes: {},
            user: inscription.data(),
            superviseur: {
                user: this.user,
                programme: {},
            },
            superviseurSaved: false,
            sending: false
        }),
        validations: {
            user: {
                nom: {
                    required,
                    minLength: minLength(4),
                    maxLength: maxLength(40)
                },
                prenom: {
                    minLength: minLength(4),
                    maxLength: maxLength(40)
                },
                courriel: {
                    required,
                    minLength: minLength(15),
                    maxLength: maxLength(40)
                },
                telephone: {
                    minLength: minLength(10),
                    maxLength: maxLength(15)
                },
                login: {
                    required,
                    maxLength: maxLength(20)
                },
                password: { 
                    required, 
                    minLength: minLength(6) },
                password_confirmation: { 
                    required, 
                    sameAsPassword: sameAs('password')
                }
            },
            superviseur: {
                programme: {
                    required
                }
            }

        },
        mounted() {
            this.chargeProgrammes();
        },
        methods:{
            /**
             * Appel ajax pour charger la liste des programmes.
             */
            chargeProgrammes() {
                axios.get('/api/programmes')
                .then(response => {
                    this.programmes = response.data.programmes;
                    this.etat = "charge";  
                })
            },
            /**
             * Permet de retourner vers la page précédante.
             */
            cancel () {
                this.$router.go(-1)
            },
            getValidationUserClass (fieldName) {
                const field = this.$v.user[fieldName]

                if (field) {
                    return {
                        'md-invalid': field.$invalid && field.$dirty
                    }
                }
            },
            getValidationProgramClass (fieldName) {
                const field = this.$v.superviseur.programme[fieldName]

                if (field) {
                    return {
                        'md-invalid': field.$invalid && field.$dirty
                    }
                }
            },
            validaterChamps () {
                this.$v.$touch()
                if (!this.$v.$invalid) {
                    this.creer()
                }
            },
            /**
             * Appel ajax pour sauvegarder la ressource.
             */
            async creer() {
                this.sending = true

                this.$children.validaterChamps()
                // Fetch the user.
                this.user = await this.$store.dispatch('auth/fetchUser')

                axios.post('/api/superviseurs/createApi', this.superviseur)
                    .then(response => {
                        this.superviseurSaved = true
                        this.$router.push({name: 'superviseurs'})

                    })
                    .catch(e => {
                        if(e.response.status==422) {
                            this.erreurs = e.response.data.errors;
                        } else {
                            window.alert('Noop')

                            // this.$swal("Une erreur s'est produite")
                        }
                    this.sending = false
                    });
            },
        }

    }
</script>

<style lang="scss" scoped>
  .md-progress-bar {
    position: absolute;
    top: 0;
    right: 0;
    left: 0;
  }
</style>


user subscription file

<template>
    <div>
        <form class="md-layout">
            <md-card class="md-layout-item md-size-100 md-small-size-100">
                <md-card-content>
                    <div class="md-layout md-gutter">
                        <div class="md-layout-item md-small-size-100">
                            <md-field :class="getValidationUserClass('nom')">
                                <label>Nom</label>
                                <md-input v-model="user.nom" :disabled="sending" placeholder="Votre nom"></md-input>
                                <span class="md-error" v-if="!$v.user.nom.required">Le champ 'nom' est requis</span>
                                <span class="md-error" v-else-if="!$v.user.nom.minLength">Nom invalide, trop court</span>
                                <span class="md-error" v-else-if="!$v.user.nom.maxLength">Nom invalide, trop long</span>
                            </md-field>

                            <md-field :class="getValidationUserClass('prenom')">
                                <label>Prénom</label>
                                <md-input v-model="user.prenom" :disabled="sending" placeholder="Votre prénom"></md-input>
                                <span class="md-error" v-if="!$v.user.prenom.minlength">Prénom invalide, trop court</span>
                                <span class="md-error" v-else-if="!$v.user.prenom.maxlength">Prénom invalide, trop long</span>
                            </md-field>

                            <md-field :class="getValidationUserClass('courriel')">
                                <label>Courriel</label>
                                <md-input v-model="user.courriel" :disabled="sending" placeholder="Votre courriel"></md-input>
                                <span class="md-error" v-if="!$v.user.courriel.required">Le champ 'courriel' est requis</span>
                                <span class="md-error" v-else-if="!$v.user.courriel.minlength">Courriel invalide, trop court</span>
                                <span class="md-error" v-else-if="!$v.user.courriel.maxlength">Courriel invalide, trop long</span>
                            </md-field>

                            <md-field :class="getValidationUserClass('telephone')">
                                <label>Téléphone</label>
                                <md-input v-model="user.telephone" :disabled="sending" placeholder="Votre téléphone"></md-input>
                                <span class="md-error" v-if="!$v.user.telephone.minlength">Téléphone invalide, trop court</span>
                                <span class="md-error" v-else-if="!$v.user.telephone.maxlength">Téléphone invalide, trop long</span>
                            </md-field>

                            <md-field :class="getValidationUserClass('login')">
                                <label>Login</label>
                                <md-input v-model="user.login" :disabled="sending" placeholder="Votre identifiant"></md-input>
                                <span class="md-error" v-if="!$v.user.login.required">Le champ 'login' est requis</span>
                                <span class="md-error" v-else-if="!$v.user.login.maxlength">Login invalide, trop long</span>
                            </md-field>

                            <md-field :class="getValidationUserClass('password')">
                                <label>Mot de passe</label>
                                <md-input v-model="user.password" :disabled="sending" placeholder="Votre mot de passe" type="password" name="password"></md-input>
                                <span class="md-error" v-if="!$v.user.password.required">Le champ 'mot de passe' est requis</span>
                                <span class="md-error" v-else-if="!$v.user.password.minlength">Mot de passe invalide, trop court</span>
                            </md-field>

                            <md-field :class="getValidationUserClass('password_confirmation')">
                                <label>Confirmez le mot de passe</label>
                                <md-input v-model="user.password_confirmation" :disabled="sending" placeholder="Votre confirmation de mot de passe" type="password" name="password_confirmation"></md-input>
                                <span class="md-error" v-if="!$v.user.password_confirmation.required">Le champ 'confirmation de mot de passe' est requis</span>
                                <span class="md-error" v-else-if="!$v.user.password_confirmation.sameAsPassword">Les mots de passe doivent correspondent</span>
                            </md-field>
                        </div>
                    </div>
                </md-card-content>
                <!--
                <md-card-actions>
                    <md-button @click="retour()" class="md-raised md-accent">Annuler</md-button>
                    <md-button @click.prevent="validaterChamps()" class="md-raised md-primary" :disabled="sending">Continuer</md-button>
                </md-card-actions>
                <md-progress-bar md-mode="indeterminate" v-if="sending" />
                -->
            </md-card>
        </form>
    </div>
</template>

<script>

    import lodash from 'lodash'
    import axios from 'axios'
    import Form from 'vform'
    import VueMaterial from 'vue-material'
    import { validationMixin } from 'vuelidate'
    import { required, minLength, maxLength, between, sameAs  } from 'vuelidate/lib/validators'

    export default {
        middleware: 'auth',
        components:{ VueMaterial, validationMixin },
        name: 'Inscription',
        mixins: [validationMixin],

        data: () => ({
            user: {
                nom: '',
                prenom: '',
                courriel: '',
                telephone: '',
                login: '',
                password: '',
                password_confirmation: ''
            },
            erreurs: {},
            sending: false,
        }),

        validations: {
            user: {
                nom: {
                    required,
                    minLength: minLength(4),
                    maxLength: maxLength(40)
                },
                prenom: {
                    minLength: minLength(4),
                    maxLength: maxLength(40)
                },
                courriel: {
                    required,
                    minLength: minLength(15),
                    maxLength: maxLength(40)
                },
                telephone: {
                    minLength: minLength(10),
                    maxLength: maxLength(15)
                },
                login: {
                    required,
                    maxLength: maxLength(20)
                },
                password: { 
                    required, 
                    minLength: minLength(6) },
                password_confirmation: { 
                    required, 
                    sameAsPassword: sameAs('password')
                }  
            }


        },
        methods: {

            validaterChamps () {
                this.$v.$touch()

                if (!this.$v.$invalid) {
                    this.register()
                }
            },
            getValidationUserClass (fieldName) {
                const field = this.$v.user[fieldName]

                if (field) {
                    return {
                        'md-invalid': field.$invalid && field.$dirty
                    }
                }
            },

            register () {
                this.sending = true
                axios.post('/api/inscription', this.user)
                    .then(response => {
                         // Save the token.
                        this.$store.dispatch('auth/saveToken', { token })

                        // Update the user.
                        this.$store.dispatch('auth/updateUser', { user: user }) 

                    })
                    .catch(e => {
                        if(e.response.status==422) {
                            this.erreurs = e.response.data.errors;
                        } else {
                            window.alert('Noop')

                            // this.$swal("Une erreur s'est produite")
                        }
                    this.sending = false
                    });


            }
        }
    }
</script>

<style lang="scss" scoped>
  .md-progress-bar {
    position: absolute;
    top: 0;
    right: 0;
    left: 0;
  }
</style>

When i'll press on the button that execute validerChamps() it should try if program is valid the send to inscription-view if the fields are valid then send back an emit method to the supervisor component that he's ready to be save and then it send the user_id to the supervisor component. Also, once supervisor gets the user_id it will send with axios the user_id and the supervisor object that contain the program to the controller related to the supervisor crud.

  • 写回答

0条回答 默认 最新

    报告相同问题?

    悬赏问题

    • ¥50 comfyui下连接animatediff节点生成视频质量非常差的原因
    • ¥20 有关区间dp的问题求解
    • ¥15 多电路系统共用电源的串扰问题
    • ¥15 slam rangenet++配置
    • ¥15 有没有研究水声通信方面的帮我改俩matlab代码
    • ¥15 ubuntu子系统密码忘记
    • ¥15 信号傅里叶变换在matlab上遇到的小问题请求帮助
    • ¥15 保护模式-系统加载-段寄存器
    • ¥15 电脑桌面设定一个区域禁止鼠标操作
    • ¥15 求NPF226060磁芯的详细资料