在所有 Vue.js 组件之间共享数据

Posted

技术标签:

【中文标题】在所有 Vue.js 组件之间共享数据【英文标题】:Sharing data between all Vue.js components 【发布时间】:2019-08-18 17:58:43 【问题描述】:

我是第一次使用 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'];

EDIT :您可以在子组件中看到一个名为 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();
        );
    

谢谢

【问题讨论】:

欢迎来到 SO!请添加您的父 html 文件以及您想要传递给父级的确切数据? 您可以在实例之间共享状态,如 here 所述,或者如果您的应用程序大小增加,Vuex 是您的最佳选择 【参考方案1】:

如果我了解您的主要问题,您可以使用 instance property 或 javascript 文件之类的东西来保存 client-side storage 中的变量。


据我了解,您需要一种方法,首先使用一个组件从 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? ?

                •   •   • 
            )
        
    , 

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

【讨论】:

以上是关于在所有 Vue.js 组件之间共享数据的主要内容,如果未能解决你的问题,请参考以下文章

Vue js 2 *私下*保存组件的数据

如何在 Vue.js 中的组件之间共享方法?

与路由器视图组件vue js共享根数据

如何在 Vue.js 中构造 api 调用?

Vue JS 3:如何将数据从一个组件传递到另一个组件?

学习前端vue怎么样?还好吗?