Как показать комментарий после отправки мгновенно без рендеринга страницы в Vue

#javascript #arrays #laravel #vue.js #render

#javascript #массивы #laravel #vue.js #рендеринг

Вопрос:

Я пытаюсь показать комментарий после нажатия на кнопку отправки. Данные комментария сохраняются в базе данных, но мне нужно обновить страницу, после чего этот комментарий появится на странице. Я хочу, чтобы мой комментарий появлялся мгновенно после нажатия на кнопку отправки. Можете ли вы рассказать мне о синтаксисе этого решения.

         <div class="form-group">
          <h1>Review Here</h1>
          <textarea
            class="form-control mb-2"
            rows="3"
            v-model="getReview.getDescription"
          ></textarea>
          <div class="row">
            <div class="col-md-6">
              <div id="ratings">
                <div id="like" class="rating">
                  <input
                    type="radio"
                    value="5"
                    v-model="getReview.getRating"
                  >
                  <input
                    type="radio"
                    value="4"
                    v-model="getReview.getRating"
                  >
                  <input
                    type="radio"
                    value="3"
                    v-model="getReview.getRating"
                  >
                  <input
                    type="radio"
                    value="2"
                    v-model="getReview.getRating"
                  >
                  <input
                    type="radio"
                    value="1"
                    v-model="getReview.getRating"
                  >
                </div>
              </div>
            </div>
            <div class="col-md-6">
              <button v-on:click="addNewReview()">Submit</button>
            </div>
  

Это мой скрипт. Я пытаюсь поместить новые данные комментария в массив отзывов, но это не работает

 <script>
export default {
  props: ["id", "usernow"],
  data() {
    return {
      reviews: [],
      orgData: {
        name_org: "",
        headerpic: "",
        description: ""
      },
      getReview: {
        getOrgId: this.id,
        getUserId: this.usernow.id,
        getRating: "",
        getDescription: ""
      }
    };
  },
  mounted() {
    this.getData();
  },
  methods: {
    addNewReview() {
      if (
        this.getReview.getDescription != "" amp;amp;
        this.getReview.getRating != 0
      ) {
        axios.post("/api/reviews", {
          org_id: this.getReview.getOrgId,
          user_id: this.getReview.getUserId,
          description: this.getReview.getDescription,
          rating: this.getReview.getRating
        });
        this.getReview.getDescription = "";
        this.getReview.getRating = 0;
        alert("OK");
      } else {
        alert("Please Review and rate this");
      }
    },
    getData() {
      axios.get("/api/listorgs/"   this.id).then(response => {
        var ArrayData = response.data;
        this.orgData = ArrayData.ListOrg;
        this.reviews = ArrayData.Review.map(review => {
          return {
            description: review.description,
            user: review.user,
            rating: review.rating,
            created_at: review.created_at
          };
        });
      });
    }
  }
};
</script>
  

Комментарии:

1. Добавьте .then в axios.post , а затем вы можете либо вызвать getData снова, либо, что более просто, просто .push новый объект в массив отзывов, содержащий новую информацию.

Ответ №1:

Исходя из getData() , я предполагаю, что каждый элемент обзора должен иметь такую форму:

 {
  description,
  user,
  rating,
  created_at
}
  

Вам пришлось бы преобразовать getReview объект в addNewReview() в требуемый формат, а затем вставить этот новый объект в reviews[] :

 addNewReview() {
  if (...) {
    axios.post(...);

    const newReview = {
      description: this.getReview.getDescription,
      user: this.getReview.getUserId,
      rating: this.getReview.getRating,
      created_at: new Date()
    };
    this.reviews.push(newReview);

    this.getReview.getDescription = '';
    this.getReview.getRating = 0;

  } else {
    ...
  }
}
  

 new Vue({
  el: '#app',
  data: () => ({
    reviews: [],
    getReview: {
      getOrgId: '',
      getUserId: 'john123',
      getRating: 3,
      getDescription: 'Lorem ipsum dolor sit amet consectetur adipisicing elit. Amet, vero quisquam laboriosam magni enim, deserunt provident facilis eaque, alias fuga velit suscipit dolorum. Modi repudiandae nihil in incidunt quis placeat.',
    }
  }),
  methods: {
    addReview(review) {
      this.reviews.push({
        created_at: new Date(),
        user: review.getUserId,
        description: review.getDescription,
        rating: review.getRating
      })
    },
    submitReview() {
      this.addReview({
        getUserId: this.getReview.getUserId,
        getDescription: this.getReview.getDescription,
        getRating: this.getReview.getRating,
      })
    }
  }
})  
 .reviews {
  list-style: none;
}
.review {
  border: solid 1px #ccc;
  padding: 1em;
  margin: 0.5em;
  border-radius: 3px;
  max-width: 450px;
}
.user {
  font-weight: bold;
}
.created_at {
  font-size: 0.8em;
  color: #888;
}
.description {
  font-style: italic;
}  
 <script src="https://unpkg.com/vue@2.6.10"></script>

<div id="app">
  <form action="#" @submit.prevent="submitReview">
    <div>
      <label>User
        <input type="text" v-model="getReview.getUserId" required>
      </label>
    </div>
    <div>
      <label>Rating
        <input type="number" min="1" max="5" v-model.number="getReview.getRating" required>
      </label>
    </div>
    <div>
      <label>Comment
        <input type="text" v-model="getReview.getDescription"></input>
      </label>
    </div>

    <button type="submit">Submit review</button>
  </form>

  <h3>Reviews ({{reviews.length}})</h3>
  <ul class="reviews">
    <li class="review" v-for="review in reviews">
      <div>
        <div class="rating">
          <span v-for="n in review.rating"></span>
        </div>
        <span class="user">{{review.user}}</span>
        <div class="created_at">{{review.created_at}}</div>
      </div>
      <p class="description">{{review.description}}</p>
    </li>
  </ul>
</div>