Vue3でTwitterクローンを作る その1
Twitterクローンを作ろう!
誰もが使ったことがある(はずの)Twitterのクローンアプリを作成して、Vue.jsの理解をより深めていきます。
TwitterのようなSNSはほどほどに複雑ですが、手を出せないほど難しいわけではありません。なので実力アップには最適だと思います。
最初はシンプルに1人のユーザーが独り言を呟くアプリという設定で作っていきます。
FormからAppにツイートのデータをオブジェクトとして渡す
App以外にFormとTweetsというコンポーネントを作り、Formで入力フォームからツイートを入力させます。
「ツイートする」ボタンを押すと、clickイベントにより$emit
を動作させて、親コンポーネントのAppにツイートのデータを渡します。
ここで、ツイートのデータを
TweetObjは最終的にバックエンド側でデータベースに接続することを念頭に主キーとなる
このほかにBootStrapが、public/index.htmlで読み込んであります。
App.vue
<template> <div class="wrapper"> <h2 class="text-success">Twitter-Vue3</h2> <div class="content"> <Form v-on:tweet-event="tweetAction" /> <Tweet /> </div> </div> </template> <script> import Form from "./components/Form.vue"; import Tweet from "./components/Tweet.vue"; export default { name: "App", components: { Form, Tweets, }, methods: { tweetAction(TweetObj){ console.log(TweetObj) } } }; </script> <style> .wrapper { width: 60%; margin: 20px auto; } .content { margin: 20px auto; width: 100%; } </style>
Form.vue
<template> <div class="form form-group"> <textarea name="form" id="" class="form-control" cols="60" rows="5" placeholder="いまなにしてる?" v-model="TweetObj.tweet_body" ></textarea> <br/> <button class="text-white bg-success" v-on:click="doTweet">ツイートする</button> </div> </template> <script> export default { name:"Form", data(){ return{ TweetObj:{ tweet_id:0, tweet_body:'' }, } }, methods: { doTweet(){ this.TweetObj.tweet_id += 1 this.$emit('tweet-event',this.TweetObj) }, }, } </script>
AppからTweetツイートのデータをオブジェクトの配列として渡す
AppコンポーネントにArray.of()
によって初回に表示するダミーデータを持った配列です。
Formコンポーネントから受け取るpush()
メソッドによって追加していきます。
また、この配列をv-for
を使って分解し、子のTweetコンポーネントに渡していきます。
TweetコンポーネントではBootStrapを使って、idを上に本文を下に表示させています。
ただし、この実装では画像の通りバグがあります。
App.vue
<template> <div class="wrapper"> <h2 class="text-success">Twitter-Vue3</h2> <div class="content"> <Form v-on:tweet-event="tweetAction" /> <div style="margin-top:20px"> <Tweet v-for="Tweet in AllTweet" v-bind:TweetObj="Tweet" v-bind:key="Tweet.tweet_id" /> </div> </div> </div> </template> <script> import Form from "./components/Form.vue"; import Tweet from "./components/Tweet.vue"; export default { name: "App", components: { Form, Tweet, }, data() { return { AllTweet: Array.of({ tweet_id: 0, tweet_body: "はじめてのツイート", }), }; }, methods: { tweetAction(TweetObj) { this.AllTweet.push(TweetObj); }, }, }; </script> // 略
Tweets.vue
<template> <div class="card"> <div class="card-header"> {{ TweetObj.tweet_id }} </div> <div class="card-body"> <div class="card-text">{{ TweetObj.tweet_body }}</div> </div> </div> </template> <script> export default { name: "Tweet", props: { TweetObj: Object, }, }; </script>
オブジェクトの参照渡しを値渡しに変更する
画像の通り、新しい呟きを追加するとこれまでのデータも最新のものに置き換わってしまいます。
これはFormコンポーネントで親にオブジェクトをそのまま渡しているのが原因です。
これは
オブジェクトを値渡しにするために、assign()
というメソッドを使うようにFormコンポーネントを修正します。
Form.vue
// 略 methods: { doTweet(){ this.TweetObj.tweet_id += 1 // 値渡しするために、新しいオブジェクトを定義する const tweet = Object.assign({},this.TweetObj) this.$emit('tweet-event',tweet) }, },
続きます。