javascript - Vue.js 将刚刚创建的数据从子组件传递到父组件

标签 javascript laravel vue.js vue-component

我有一个 Vue.js/Laravel 应用程序,在其中我正在努力完成一项简单的任务。我有一个名为 Create 的子组件,它在数据库中创建一个新项目,并且应该将这个新创建的数据发送到父组件,以便我将这个新创建的数据包含到名为 jobs 的父组件上的数组中。这实际上不起作用,我必须刷新页面才能在父组件上看到它。谁能帮我解决这个问题吗?

这是我的子组件Create.vue

<template>
  <div class="modal-backdrop">
    <div class="modal">
      <header class="modal-header">
        <slot name="header">
          <h3>Create new position</h3>
          <button type="button" class="btn-close" @click="close">
            x
          </button>
        </slot>
      </header>
      <section class="modal-body">
        <slot name="body">
                    <label for="title">Title</label>
                    <input v-model="job.name" type="text" name="name" class="form-control" required>

                    <label for="salary">Salary / Amount (k) per year (eg.:30, 40, 65)</label>
                    <input v-model="job.salary" type="number" name="salary"  class="form-control">

                    <label for="location">Location</label>
                    <input v-model="job.location" type="text" name="location" class="form-control" required>

                    <label for="experience">Years of experience eg.:1,2,4,5</label>
                    <input v-model="job.experience_years" type="number" name="experience_years" class="form-control" required>

                    <label for="benefits">Bonus - Benefits</label>
                    <input v-model="job.bonus" type="text" name="bonus" class="form-control">

                    <label for="description">Description / Job details</label>
                    <textarea v-model="job.description" rows="4" cols="50" name="description" class="form-control large"></textarea>
                    <br>

                    <input @click="saveJob" type="button" class="btn btn-primary" value="Save">
        </slot>
      </section>
      <footer class="modal-footer">
    </footer>
  </div>
</div>
</template>

<script>
 import moment from 'moment';
  export default {
    name: 'Create',

    data(){
        return{
            jobs: [],
            job: {id:'', name:'', description:'', salary:'', location:'', experience_years:'', bonus:'', expiration:'', created_at:''},
        }
    },

    methods:{

      close(job){
        this.$emit('newJob', job);
        this.$emit('closeCreateRequest');
      },

      moment,

      saveJob(){
          axios.post('http://localhost:8888/fintechjobs.io/public/api/job/createJob',this.job).then((response) => {
              this.close(this.job);
        }).catch((error) => this.errors = error.response.data.errors);

      }

    }
  }
</script>

<style>
  .modal-backdrop {
    position: fixed;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
    background-color: rgba(0, 0, 0, 0.3);
    display: flex;
    justify-content: center;
    align-items: center;
  }

  .modal {
    background: #FFFFFF;
    box-shadow: 2px 2px 20px 1px;
    overflow-x: auto;
    display: flex;
    flex-direction: column;
    left:25%;
    margin-left:15%px;
    position:fixed;
    width:50%;
    height: 70%;
    top:10%;
    overflow-y: auto;
    /* border: 1px black solid; */
  }

  .modal-header,
  .modal-footer {
    padding: 15px;
    display: flex;
    border: none!important;
  }

  .modal-header {
    /* border-bottom: 1px solid #eeeeee; */
    color: #214761;
    justify-content: space-between;
  }

  .modal-footer {
    /* border-top: 1px solid #eeeeee; */
    justify-content: flex-end;
  }

  .modal-body {
    position: relative;
    padding: 20px 20px;
    position: relative;
    padding: 20px 10px;
    margin-top: 30px;
    margin-left: 7px;
  }

  .btn-close {
    border: none;
    font-size: 20px;
    padding: 18px;
    cursor: pointer;
    font-weight: bold;
    color: #214761;
    background: transparent;
  }

  .btn-green {
    color: white;
    background: #4AAE9B;
    border: 1px solid #4AAE9B;
    border-radius: 2px;
  }


</style>

这是父组件Vancancies.vue,它应该接收数据并插入到作业列表中:

<template>
    <div id="page-wrapper" >
    <div id="page-inner">
        <div class="row">
            <div class="col-lg-12">
                <h2>My job vacancies</h2>
                <!--  if(count($positions) > 0) { echo "";} else{ echo "No positions for the moment!"; -->

            <button v-if="this.company_remaining_jobs > 0" @click="openJobCreateModal" type="button" class="btn btn-primary modal-primary" data-toggle="modal" data-target="#exampleModalLong" >Create position</button>

                <table class="table table-bordered">
                    <thead>
                        <tr>
                            <th>Title</th>
                            <th>Created</th>
                            <th></th>
                        </tr>
                    </thead>
                     <tbody>
                         <tr v-for="job in jobs.jobs" :key="job.id" :job="job">
                            <td>{{job.name}}</td>
                            <td>{{moment(job.created_at).fromNow()}}</td>
                            <td style="text-align:center">
                                <button @click="openViewJobModal(job)" class="btn btn-large btn-success">View</button>
                                <button class="btn btn-large btn-primary">Edit</button>
                            </td>
                        </tr>
                    </tbody>
                </table>
        </div>
        <!-- endif -->
            </div>
        </div>
        <Show v-if="viewJobModalVisible" :job="job" @closeRequest='closeJobViewModal'></Show>
        <Create v-if="createJobModalVisible" @closeCreateRequest='closeJobCreateModal' @newJob='getNewJob'></Create>
    </div>
</template>

<script>

    import axios from 'axios';
    import moment from 'moment';
    import Show from './Show.vue';
    import Create from './Create.vue';

    export default {

        data(){

            return {
                jobs: [],
                job: {id:'', name:'', description:'', salary:'', location:'', experience_years:'', bonus:'', expiration:'', created_at:''},
                viewJobModalVisible: false,
                createJobModalVisible: false,
                company_remaining_jobs: '',
                newJob:''
            }

        },

        methods:{

            getJobs(){
                axios.get('http://localhost:8888/fintechjobs.io/public/api/vacancies').then( response => {
                    this.jobs = response.data
                }).catch(e => {
                    console.log(e);
                })
            },

            getCompanyInfo(){
                axios.get('http://localhost:8888/fintechjobs.io/public/api/company_info').then(response =>{
                    this.company_remaining_jobs = response.data.company_remaining_jobs;
                })
            },

            moment,

            openViewJobModal(job){
                this.job = job;
                this.viewJobModalVisible = true;
            },

            closeJobViewModal(){
                this.job = '';
                this.viewJobModalVisible = false;
            },

            openJobCreateModal(){
                this.createJobModalVisible = true;
            },

            closeJobCreateModal(){
                this.createJobModalVisible = false;
            },

            getNewJob(value){
                console.log(value);
                this.jobs.push(value)
            }
        },

        mounted(){
            this.getJobs();
            this.getCompanyInfo();
        },

        components:{
            Show,
            Create
        }


    }
</script>

奇怪的是,这就是我在控制台上看到刚刚创建的数据和错误的方式: enter image description here enter image description here

最佳答案

我认为问题在于您最初的 getJobs() 调用来填充 jobs 正在用对象覆盖空数组,并且 .push() 方法不适用于对象。这方面的证据可以在引用 jobs.jobs 时看到,因为只有对象才能拥有命名属性:

// jobs must be an Object to have a named property
<tr v-for="job in jobs.jobs" :key="job.id" :job="job">

// ideally, this would be 
<tr v-for="job in jobs" :key="job.id" :job="job">

假设您的现有作业当前正在正确填充,请通过更改此行以及上面的行来编辑 getJobs() 方法:

this.jobs = response.data;

// try changing to
this.jobs = response.data.jobs;

关于javascript - Vue.js 将刚刚创建的数据从子组件传递到父组件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57945079/

相关文章:

javascript - Dialogflow 实现访问代码中的实体

php - 来自数据库的 LARAVEL 输入值

php - 有没有关于如何在 "Laravel 5.1"中为基于 CRUD 的应用程序编写测试的示例?

php - laravel updateOrCreate 方法

javascript - 如何在 Electron 上请求 MIDI 设备权限?

javascript - 模块误差 Angular 1.5

javascript - 无法在 &lt;script&gt; 标签内回显 PHP 变量?

javascript - Lodash `get` 方法在 Vue 应用程序的版本之间表现不一致

vue.js - VuePress - Algolia 增加结果

javascript - 在 Vue.js 上,当用户点击后退按钮时,v-model 不会保留该值