5
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Vue.jsでコメント投稿機能を作ってみた。

Posted at

1.はじめに

今回はjavascriptのフレームワーク、Vue.jsを使って投稿機能を作ってみました。vue.jsを学ぶ際によく題材として使われるToDo管理リストに少し手を加えたもので、映画の感想と評価点を投稿するサイトをイメージして作りました。

2.環境

今回も前回に引き続き、VSCodeを使用して書いていきます。 またVue.jsはVue.js公式ページのCDNのリンクを直接HTML内のbodyタグの一番下に埋め込んで使います。

3.完成体

テキストボックスの中にコメントを打ち込み、隣の選択ボタンで星の数に応じた評価点を選択します。 スクリーンショット 2019-10-20 17.17.53.png 送信ボタンを押すと投稿が完了しました。ちなみに、テキストボックスの中身が未入力の状態で送信ボタンを押しても投稿はされません。 スクリーンショット 2019-10-20 17.18.10.png 二つ目の投稿をします。するとこの二つの投稿の評価数の平均を計算して評価点が3.50になりました。 スクリーンショット 2019-10-20 17.18.47.png 三つ目の投稿をしても同じように評価点の平均点を計算します。しかし割り切れない数などある為、toFixedメソッドを使って小数点第二位までしか表示されません。そして今回は各投稿の下にあるdeleteボタンを押すと、 スクリーンショット 2019-10-20 17.19.13.png コメントが一つ消されました。 スクリーンショット 2019-10-20 17.19.33.png

次に送信ボタンの横に⬇︎⬆︎のボタンがありますが押すと、各投稿の評価点をフックに投稿を並び替えてくれます。⬇︎ボタンで評価の高い順、
スクリーンショット 2019-10-20 17.20.18.png

⬆︎ボタンで評価の低い順です。
スクリーンショット 2019-10-20 17.20.28.png

4.完成コード

index.html
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>投稿</title>
</head>

<body>
    <div class="container" id="app" v-cloak>
        <h1>評価</h1>
        <div v-if="length">
            <h2>評価点 : {{averageScore}}</h2>
        </div>
        <form v-on:submit.prevent>
            <input type="textarea" v-model="comment">
            <select v-model="rate">
                <option value="0">☆☆☆☆☆</option>
                <option value="1">★☆☆☆☆</option>
                <option value="2">★★☆☆☆</option>
                <option value="3">★★★☆☆</option>
                <option value="4">★★★★☆</option>
                <option value="5">★★★★★</option>
            </select>
            <button v-on:click="submit">送信</button>
            <button v-on:click="sort">⬇︎</button>
            <button v-on:click="sortUp">⬆︎</button>
        </form>
        <div v-for="(comment , index) in comments">
            <ul>
            <li>満足度 : <span>{{'★'.repeat(comment.rate)}}</span></li>
            <p>コメント : <span>{{comment.comment}}</span></p>
            <button v-on:click="deleteItem(index)">delete</button>
            </ul>
            
        </div>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script src="main.js"></script>
</body>

</html>
main.js


let app = new Vue({  //vueインスタンス生成
    el: '#app', //id="app"が属性として使用されているタグ内で使える。(マウント)
    data: {
        comment: "",
        rate: 0,
        comments: [],
        sun: 0,
        length: false,  //使いたい変数達

    },
    methods: {  //各メソッドを格納。htmlを見てもらえると「v-on:click="メソッド名"」と記述されているところが複数箇所ありますが要素をクリックした際に下記のメソッドを実行するという意味です。
        submit: function () {
            if (this.comment == "") return;
            if (this.comment.length > 100) return;
            let commentItem = {
                comment: this.comment,
                rate: this.rate
            }
            this.comments.unshift(commentItem);
            this.sun = this.sun + Number(commentItem.rate)
            this.comment = ""
            this.rate = 0
            if (this.comments.length > 0) {
                this.length = true
            }
        },
        deleteItem: function (index) {
            this.sun = this.sun - Number(this.comments[index].rate);
            this.comments.splice(index, 1);
            if (this.comments.length < 1) {
                this.length = false
            }
        },
        sortUp:function(){
            let arr =  this.comments;
            arr.sort(function(a,b){
                if (a.rate > b.rate) return 1;
	            if (a.rate < b.rate) return -1;
	            return 0;
            })
            this.comments = arr;
        },
        sort:function(){
            let arr =  this.comments;
            arr.sort(function(a,b){
                if (a.rate > b.rate) return -1;
	            if (a.rate < b.rate) return 1;
	            return 0;
            })
            this.comments = arr;
        },
        

        
    },
    computed:{  //算出プロパティと言います。変数averageScoreをhtml側で呼び出すと
//自動的に関数内の処理を実行してくれます。他にも監視プロパティというものもありますが監視プロパティに比べて
//処理結果をキャッシュしてくれるというのが大きな特徴です。
        averageScore:function(){
            return (this.sun/this.comments.length).toFixed(2)
        }
        
    }

})

終わりに

以上です。今回は前回に比べてスッキリした解説でしたが実際に手を動かして興味のある方はコピぺしながら勉強をしていただけると幸いです。
5
5
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?