フォームイメージ
Vue.jsでモーダルウィンドウで投稿フォームを表示してコメントを投稿できる仕組みにしています
投稿はできるのですがリロードしないとコメントができないようになってしまいます
どのようにすれば非同期で表示できるのでしょうか?
<template> <div class="tweet-comment"> <div v-for="e in text" :key="e.id"> {{e.comment}} </div> <modal name="comment-modal"> <form @submit.prevent="createComment"> <div v-if="errors.length != 0"> <ul v-for="e in errors" :key="e"> <li><font color="red">{{ e }}</font></li> </ul> </div> <div class="tweet-comment_form"> <input v-model="comment.text" type="text"> </div> <button type="submit" @click="registerModal">投稿する</button> </form> </modal> <button class="btn btn-primary my-2" @click="showModal(); resetForm()">コメント投稿</button> </div> </template> <script> import axios from 'axios' export default { data() { return { comment: { text: '' }, text: [], errors: '' } }, mounted() { this.fetchComments() }, methods: { createComment: function() { axios .post(`/api/v1/tweets/${this.$route.params.id}/comments`,this.comment) .then(response => { let e = response.data; }) .catch(error => { console.error(error); if (error.response.data && error.response.data.errors) { this.errors = error.response.data.errors; } }); }, fetchComments() { axios .get(`/api/v1/tweets/${this.$route.params.id}/comments.json`) .then(response => { this.text = response.data }) }, showModal(){ this.$modal.show('comment-modal'); }, registerModal(){ this.$modal.hide('comment-modal'); }, resetForm(){ this.comment.text = ''; }, } } </script>
###追記
Railsと組み合わせてコメント機能を作っています
コントローラーでデータベースからjson形式でデータを取得しています
class Api::V1::CommentsController < ApiController # ActiveRecordのレコードが見つからなければ404 not foundを応答する rescue_from ActiveRecord::RecordNotFound, with: :render_status_404 def index @comments = Comment.where(tweet_id: params[:tweet_id]) render 'index', formats: 'json', handlers: 'jbuilder' end def create comment = Comment.new(comment_params) if comment.save render json: comment,status: :created else render json: { errors: comment.errors.full_messages }, status: :unprocessable_entity end end private def comment_params params.require(:comment).permit(:text).merge(user_id: current_user.id,tweet_id: params[:tweet_id]) end end
####Vue
<div class="comment-content_tweet"> <div id="comments_area"> <div v-for="e in text" :key="e.id"> {{e.comment}} </div> </div> <div class="comment-form"> <form @submit.prevent="createComment"> <div v-if="errors.length != 0"> <ul v-for="e in errors" :key="e"> <li><font color="red">{{ e }}</font></li> </ul> </div> <div class="tweet-comment_form"> <textarea v-model="comment.text" type="text"></textarea> </div> <button type="submit" class="game_record" >投稿する</button> </form> </div> </div> </div> </div> </template> <script> <script> import axios from 'axios' data() { return { comment: { text: '' }, errors: '' } }, mounted() { this.fetchTweets() this.fetchComments() }, methods: { fetchComments() { axios .get(`/api/v1/tweets/${this.$route.params.id}/comments.json`) .then(response => { this.text = response.data }) }, createComment: function() { axios .post(`/api/v1/tweets/${this.$route.params.id}/comments`,this.comment) .then(response => { let e = response.data; this.fetchComments() }) .catch(error => { console.error(error); if (error.response.data && error.response.data.errors) { this.errors = error.response.data.errors; } }); } } } </script>
####解決
data() { return { comment: "", text: "", errors: '' } }, mounted() { this.fetchComments() }, methods: { //コメント fetchComments() { axios .get(`/api/v1/tweets/${this.$route.params.id}/comments`) .then(response => { this.comment = response.data }) }, createComment: function() { axios .post(`/api/v1/tweets/${this.$route.params.id}/comments`,{text: this.text}) .then(response => { // this.text = response.data; this.fetchComments() }) .catch(error => { console.error(error); if (error.response.data && error.response.data.errors) { this.errors = error.response.data.errors; } }); }
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2021/03/18 11:48
2021/03/18 15:18
2021/03/18 15:33
2021/03/18 15:41
2021/03/18 15:58
2021/03/18 16:12
2021/03/19 11:14
2021/03/19 11:45
2021/03/19 12:21
2021/03/19 16:08