首页 > 解决方案 > 在所有 Vue.js 组件之间共享数据

问题描述

我第一次使用 Laravel/Vue.js 构建一个 CRUD Web 应用程序。我正在使用 MySQL 数据库,并且使用了许多 Vue.js 组件,每个组件都可以访问数据库中的一个表。现在我需要制作一些组件来从其他组件中获取数据以在下拉列表中使用它,但我无法弄清楚。

我尝试使用道具,但总是出错。

这是在子 vue 中:

<div class="form-group">
<select v-model="form.fabnom" type="text" name="fabnom" id="fabnom" class="form-control" :class="{ 'is-invalid': form.errors.has('fabnom') }">
    <option v-for="fabriquant in fabriquants" :key="fabriquant.id" :value="fabriquant.fabnom">
    </option>
</select>
<has-error :form="form" field="fabnom"></has-error>

<script>
    export default {
        data(){
            return{
                editmode: false,
                machines :{},
                form: new Form({
                    id:'',
                    code:'',
                    nom: '',
                    type:'',
                    serie:'',
                    date:'',
                    fabnom:'',
                    section:'',
                    unite:''                 
                })
            }
        }  ,  

这是api:

Route::apiResources([
'user' => 'API\UserController',
'fabriquant' => 'API\FabriquantController',
'machine' => 'API\MachineController',]);

子控制器(父控制器几乎相同):

public function index()
{
    //$this->authorize('isAdmin');
    if (\Gate::allows('isAdmin')) {
        return Machine::latest()->paginate(5);
    }
}


public function store(Request $request)
{
    $this->validate($request,[
        'code'             => 'required|string|max:191|unique:machines',
        'nom'             => 'required|string|max:191',
        'type'             => 'max:191',
        'serie'             => 'max:191',
        'date'             => 'max:191',
        'fabnom'             => 'max:191',
        'section'             => 'max:191',
        'unite'             => 'max:191',
    ]);

    return Machine::create([
          'code'=> $request['code'],
          'nom'=> $request ['nom'],
          'type'=> $request['type'],
          'serie'=> $request['serie'],
          'date'=> $request['date'],
          'fabnom'=> $request['fabnom'],
          'section'=> $request['section'],
          'unite'=> $request['unite'],
    ]);
}

public function show($id)
{
    //
}


public function update(Request $request, $id)
{
    $machine = Machine::findOrFail($id);
    $this->validate($request,[
        'code'             => 'required|string|max:191|unique:machines,code,'.$machine->id,
        'nom'             => 'max:191',
        'type'             => 'max:191',
        'serie'             => 'max:191',
        'date'             => 'max:191',
        'fabnom'             => 'max:191',
        'section'             => 'max:191',
        'unite'             => 'max:191',
    ]);
    $machine->update($request->all());
    return ['message' => 'Updated'];
}


public function destroy($id)
{
    $machine = Machine::findOrFail($id);
    // delete
    $machine->delete();
    return ['message' => 'Deleted'];
}

}

编辑:您可以在子组件中看到一个名为 fabnom 的字符串,在父组件中也有一个:所以现在让我们说我在父组件中,我通过模式向其数据库添加了 3 个项目,每个项目有 6 列在数据库中,其中一个称为 fabnom ,现在我传递到子组件页面,我打开了一个“addNew”模型,并且有一个标记为 fabnom 的下拉框,其中应该有我已经添加的 3 个选项,我选择其中一个值将存储在子组件数据库的 fabnom 列中(我希望你们能理解):)

这是 parent.vue (孩子看起来很相似,唯一的区别是它的“addNew”模型中还有一个下拉框,因为它是导致问题的原因):

<template>
<div class="container">
    <div class="row mt-5" v-if="$gate.isAdmin()">
            <div class="col-md-12">
                <div class="card">
                <div class="card-header">
                    <h3 class="card-title">Liste des Fabriquants</h3>

                    <div class="card-tools">
                        <button class="btn btn-success" @click="newModal">
                            Ajouter</button>                   
                    </div>

                </div>
                <!-- /.card-header -->
                <div class="card-body table-responsive p-0">
                    <table class="table table-hover">
                    <tbody>
                    <tr>
                        <th>Nom</th>
                        <th>Adresse</th>
                        <th>Téléphone</th>
                        <th>Fax</th>
                        <th>E-mail</th>
                    </tr>

                    <tr v-for="fabriquant in fabriquants.data" :key="fabriquant.id">

                        <td>{{fabriquant.fabnom}}</td>
                        <td>{{fabriquant.adresse}}</td>
                        <td>{{fabriquant.tel}}</td>
                        <td>{{fabriquant.fax}}</td>
                        <td>{{fabriquant.email}}</td>   
                        <td>
                            <a href="#" @click="editModal(fabriquant)">
                                <i class="fa fa-edit"></i>
                            </a>
                            /
                            <a href="#" @click="deleteFabriquant(fabriquant.id)">
                                <i class="fa fa-trash"></i>
                            </a>
                        </td>
                    </tr>

                    </tbody></table>
                </div>
                <!-- /.card-body -->
                <div class="card-footer">
                        <pagination :data="fabriquants" @pagination-change-page="getResults"></pagination>
                    </div>

                </div>
                <!-- /.card -->
            </div>
        </div>

        <div v-if="!$gate.isAdmin()">
            <not-found></not-found>
        </div>
         <!-- Modal -->
        <div class="modal fade" id="Ajouter" tabindex="-1" role="dialog" aria-labelledby="AjouterLabel" aria-hidden="true">
                            <div class="modal-dialog modal-dialog-centered" role="document">
                            <div class="modal-content">
                                <div class="modal-header">
                                    <h5 class="modal-title" v-show="!editmode" id="AjouterLabel">Ajouter</h5>
                                    <h5 class="modal-title" v-show="editmode" id="AjouterLabel">Modifier</h5>
                                <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                                    <span aria-hidden="true">&times;</span>
                                </button>
                                </div>

                                <form @submit.prevent="editmode ? updateFabriquant() : createFabriquant()">
                            <div class="modal-body">


                                <div class="form-group">   
                                        <input v-model="form.fabnom" type="text" name="fabnom"
                                        placeholder="Nom"
                                        class="form-control" :class="{ 'is-invalid': form.errors.has('fabnom') }">
                                        <has-error :form="form" field="fabnom"></has-error>

                                </div>


                                <div class="form-group">
                                    <input v-model="form.adresse" type="text" name="adresse"
                                    placeholder="Adresse"
                                    class="form-control" :class="{ 'is-invalid': form.errors.has('adresse') }">
                                        <has-error :form="form" field="adresse"></has-error>
                                    </div>

                                <div class="form-group">
                                        <input v-model="form.tel" type="text" name="tel"
                                        placeholder="Téléphone"
                                        class="form-control" :class="{ 'is-invalid': form.errors.has('tel') }">
                                            <has-error :form="form" field="tel"></has-error>
                                    </div>


                                <div class="form-group">
                                        <input v-model="form.fax" type="text" name="fax"
                                        placeholder="Fax"
                                            class="form-control" :class="{ 'is-invalid': form.errors.has('fax') }">
                                        <has-error :form="form" field="fax"></has-error>
                                        </div>

                                <div class="form-group">
                                        <input v-model="form.email" type="email" name="email"
                                        placeholder="E-mail"
                                            class="form-control" :class="{ 'is-invalid': form.errors.has('email') }">
                                        <has-error :form="form" field="email"></has-error>
                                        </div>

                            </div>

                                <div class="modal-footer">
                                <button type="button" class="btn btn-danger" data-dismiss="modal">Fermer</button>
                                <button v-show="editmode" type="submit" class="btn btn-success">Modifier</button>
                                <button v-show="!editmode" type="submit" class="btn btn-primary">Ajouter</button>
                                </div>

                            </form>
                            </div>
                            </div>
         </div>  

</div>

<script>
export default {
    data(){
        return{
            editmode: false,
            fabriquants :{},
            form: new Form({
                id:'',
                fabnom:'',
                adresse: '',
                tel:'',
                fax:'',
                email:''
            })
        }
    },
    methods: {
        getResults(page = 1) {
                    axios.get('api/fabriquant?page=' + page)
                        .then(response => {
                            this.fabriquants = response.data;
                        });
            },
        updateFabriquant(){
            this.$Progress.start();
            // console.log('Editing data');
            this.form.put('api/fabriquant/'+this.form.id)
            .then(() => {
                // success
                $('#Ajouter').modal('hide');
                 Swal.fire(
                    'Modifié!',
                    'Informations modifiés!',
                    'success'
                    )
                    this.$Progress.finish();
                    Fire.$emit('AfterCreate');
            })
            .catch(() => {
                this.$Progress.fail();
            });
        },
        editModal(fabriquant){
            this.editmode = true;
            this.form.reset();
            $('#Ajouter').modal('show');
            this.form.fill(fabriquant);
        },
        newModal(){
            this.editmode = false;
            this.form.reset();
            $('#Ajouter').modal('show');
        },
        deleteFabriquant(id){
            Swal.fire({
                title: 'Voulez vous vraiment supprimer cet fabriquant?',
                text: "You won't be able to revert this!",
                type: 'warning',
                showCancelButton: true,
                confirmButtonColor: '#3085d6',
                cancelButtonColor: '#d33',
                confirmButtonText: 'Oui, Supprimer!',
                }).then((result) => {
                    // Send request to the server
                     if (result.value) {
                            this.form.delete('api/fabriquant/'+id).then(()=>{
                                    Swal.fire(
                                    'Supprimé!',
                                    'Element supprimé.',
                                    'success'
                                    )
                                Fire.$emit('AfterCreate');
                            }).catch(()=> {
                                Swal.fire("Echec!", "Il y'a un problème.", "warning");
                            });
                     }
                })
        },
        loadFabriquants(){
            if(this.$gate.isAdmin()){
                axios.get("api/fabriquant").then(({ data }) => (this.fabriquants = data));
            }
        },
        createFabriquant(){
            this.$Progress.start();
            this.form.post('/api/fabriquant')
            .then(()=>{
            Fire.$emit('AfterCreate');
            $('#Ajouter').modal('hide');
            toast.fire({
                type: 'success',
                title: 'Fabriquant ajouté',
            })
            this.$Progress.finish();
        })
        .catch(()=>{

        })
    }
    },
    created() {
        this.loadFabriquants();
        Fire.$on('AfterCreate',()=>{
            this.loadFabriquants();
        });
    }
}

谢谢

标签: laravelvue.js

解决方案


如果我了解您的主要问题,您可以使用实例属性或 javascript 文件之类的东西在客户端存储中保存变量。


据我了解,您需要一种方法,首先使用一个组件从 MySQL 获取数据,然后在所有其余组件中使用该数据。如果是这样,大约 2 个月前,我对当前的项目有这个需求。

唯一的问题是我没有使用 Laravel/Vue 而是Vue.jsVueApolloGraphQL。虽然,我很确定 -并且希望- 我解决问题的方式只会在语法上与您解决问题的方式不同。


我使用一个组件在用户登录后立即向他们查询一些信息。

Vue/Apollo 查询

apollo: {
  // Simple query that gets user info
  me: {
    query: gql`  //GraphQL
      {
        me {
          id
          fullName
        }
      }
    `,
    loadingKey: "isLoading" //tracks results that are still loading.
  }
}

然后我想将用户的“全名”存储在某个地方,以便我的导航组件可以始终使用它。所以我创建了一个文件:

src/config/credentialStore.js

在这个文件中,我创建了一个 displayName 变量,如下所示:

export const credentialStore = {
  displayName: "",
  userID: ""
};

回到我有“我”查询的组件中,我用一个函数解构了从查询返回的数据。

apollo: {
  // Simple query that gets user info
  me: {
    query: gql`
      {
        me {
          id
          fullName
        }
      }
    `,
    loadingKey: "isLoading",
    result({ data }) {   //data is basically an object with the results of the query

      this.$credentials.userId = data.me.id;
      this.$credentials.displayName = data.me.fullName;  
    } //using this.$credentials.displayName will let me use that string from any component.
  }
}

所以你会做这样的事情,然后可能是这样的:

<script>
export default {
    data(){
        return{
            editmode: false,
            fabriquants :{},
            form: new Form({
                id: this.$credentialStore.id,
                fabnom:this.$credentialStore.fabnom, //what's a fabnom? 

                •   •   • 
            })
        }
    }, 

我希望这对您或其他人有所帮助。


推荐阅读