LoginSignup
0
0

More than 3 years have passed since last update.

Day2:3日でVue.jsを用いたアプリケーションを動かす

Last updated at Posted at 2020-05-05

2日目の取組の記録

【Story】

・Componentを使うぞ!!!
・脱SPAしてProjectを使うぞ!!!!
・なんかそれっぽく動くものができた...!!!

【Vue.jsの応用①】

*コンポーネントの基本
script内でHTMLのタグを自動生成して返してくれるから楽


<!DOCTYPE html>
<html>
<head>
    <title>My first Vue app</title>
    <script src="http://localhost:8098"></script>
    <script src="https://unpkg.com/vue"></script>
</head>

<body>
        <style>
        .hello{
            font-size:20pt;
            font-weight:bold;
            border:1px solid magenta;
            padding:5px 10px 0px 10px;
            margin:10px;
        }
        </style>

        <h1>Vue.js</h1>

        <div id = "app">
            <hello/>
        </div>

        <script>
            Vue.component(
                'hello',
                {template: '<p class="hello">Hello!</p>'}
            )

            var app = new Vue({
                el: '#app',
            });

        </script>
</body>
</html>

*やったことはこんな感じ

・コンポーネント内に変数を利用する

<body>
        <style>
        .hello{
            font-size:20pt;
            font-weight:bold;
            border:1px solid magenta;
            padding:5px 10px 0px 10px;
            margin:10px;
        }

        </style>

        <h1>Vue.js</h1>

        <div id = "app">
            <hello/>
        </div>

        <script>
            Vue.component(
                'hello',
                {
                    data:function(){
                        return { 
                            message:'これはメッセージです。'
                        };
                    },
                    template: '<p class="hello">{{message}}</p>',
                }
            )

            var app = new Vue({
                el: '#app',
            });

        </script>
</body>

・コンポーネント内の変数にHTMLから値を引き渡す

 <body>
        <style>
        .hello{
            font-size:20pt;
            font-weight:bold;
            border:1px solid magenta;
            padding:5px 10px 0px 10px;
            margin:10px;
        }
        </style>

        <h1>Vue.js</h1>

        <div id = "app">
            <div><hello name="Taro" /></div>
            <div><hello name="Hanako" /></div>
        </div>

        <script>
            Vue.component(
                'hello',
                {
                    //props:['name'],
                    props:{ name:String },
                    template: '<p class="hello">Hello , {{name}}</p>',
                }
            )

            var app = new Vue({
                el: '#app',
            });

        </script>
</body>

・コンポーネントの再利用
※変数値はリスト型で指定
※v-for/v-bindを利用

<body>
        <style>
        .hello{
            font-size:20pt;
            font-weight:bold;
            border:1px solid magenta;
            padding:5px 10px 0px 10px;
            margin:10px;
        }

        </style>

        <h1>Vue.js</h1>

        <div id = "app">
            <hello v-for="item in data" v-bind:name="item" />
        </div>

        <script>
            Vue.component(
                'hello',
                {
                    props:['name'],
                    template: '<p class="hello">Hello , {{name}}</p>',
                }
            )

            var app = new Vue({
                el: '#app',
                data:{
                    data:['Hana','Taro','Mana']
                }
            });

        </script>
</body>

・ ユーザーが入力した内容をコンポーネントに反映する

<body>
        <style>
        .hello{
            font-size:20pt;
            font-weight:bold;
            border:1px solid magenta;
            padding:5px 10px 0px 10px;
            margin:10px;
        }
        </style>

        <h1>Vue.js</h1>

        <div id = "app">
            <div><hello v-bind:name="name" /></div>
            <div><input type="text" v-model="name"></div>
        </div>

        <script>
            Vue.component(
                'hello',
                {
                    props:['name'],
                    template: '<p class="hello">Hello , {{name}}</p>',
                }
            )

            var app = new Vue({
                el: '#app',
                data: {
                    name:'no-name'
                }
            });

        </script>
</body>

・クリックしたら回数が1ずつ増えていくカウンターを作る
※v-onを利用

<body>
        <style>
        .hello{
            font-size:20pt;
            font-weight:bold;
            border:1px solid magenta;
            padding:5px 10px 0px 10px;
            margin:10px;
        }
        </style>

        <h1>Vue.js</h1>

        <div id = "app">
            <hello />
        </div>

        <script>
            Vue.component(
                'hello',
                {
                    data:function(){
                        return {counter:0};
                    },
                    template: 
                    '<p v-on:click ="counter++;" class="hello">clicked:{{counter}}.</p>',
                }
            )

            var app = new Vue({
                el: '#app',
            });

        </script>
</body>

・カウンターをメソッド化して条件分岐
※v-on/v-ifを利用

<body>
        <style>
        .red {
        color:white;
        background-color:red;
        }
        </style>

        <h1>Vue.js</h1>

        <div id = "app">
            <hello />
        </div>

        <script>
        var hello = Vue.component(
            'hello',
            {
                data:function(){
                    return {
                        counter:0,
                        isRed:false,
                    }
                },

                methods:{
                    doAction:function(event){
                        this.counter++;
                        if(this.counter > 10){
                            this.counter = 0;
                        }
                        if(this.counter % 2){
                            this.isRed = false;
                        } else {
                            this.isRed = true;
                        }
                    },
                },

                template: '<p v-bind:class="{red:isRed}" ' + 
                'v-on:click="doAction" class="hello">clicked: {{counter}}.</p>',

            })

        var app = new Vue({
            el:'#app',
            });

        </script>
</body>

・ユーザーが入力するとどんどん加算されるメソッドを作るよ

<body>
        <style>
        </style>

        <h1>Vue.js</h1>

        <div id = "app">
            <hello />
        </div>

        <script>
        Vue.component(
            'hello',
            {
                data:function(){
                    return {
                        num : 0,
                        message : 'type a number'
                    };
                },

                methods:{
                    calc:function(event){
                        var total=0;
                        for (var i=1; i<=this.num; i++ ){
                            total += i;
                        }
                        this.message = "total: " + total; 
                    }
                },

                template:'<div><p class="hello">{{message}}</p>' +
                    '<div><input type="number" v-on:input="calc" v-model="num">' +
                    '</div></div>'
            }
        );

        var app = new Vue({
            el:'#app'
        });
        </script>
</body>

算術プロパティを使ってみるよ
※computed

 <body>
        <style>
        </style>

        <h1>Vue.js</h1>

        <div id = "app">
            <hello />
        </div>

        <script>
        Vue.component(
            'hello',
            {
                data:function(){
                    return {
                        num:0,
                    }
                },
                computed:{
                    calc:function(event){
                        var total=0;
                        for(var i=1; i<=this.num; i++){
                            total +=i;
                        }
                        return "total: " + total;
                    }
                },
                template:'<div><p class="hello">{{calc}}</p>'+
                    '<div><input type="number" v-model="num"></div></div>'
            }
        );

        var app = new Vue({
            el: '#app',
        });
        </script>
</body>

・ローカルコンポーネントを使ってみるよ
※今までのはグローバルコンポーネント

<body>
        <style>
        </style>

        <h1>Vue.js</h1>

        <div id = "app">
            <div><hello /></div>
            <div><hello /></div>
            <div><hello /></div>
        </div>

        <script>
            var app = new Vue({
                el:'#app',
                components:{
                    hello:{
                        data:function(){
                            return {
                                counter:0,
                            };
                        },

                        template:'<p v-on:click="counter++;" class="hello">' +
                                'clicked: {{counter}}.</p>',
                        }
                    }
            });

        </script>
</body>

*v-onとcomputedの違いって何?
イベント:ユーザが操作するなどしてイベントが発生すると呼び出される
算術プロパティ:依存する値が更新された時に実行

【Vue.jsの応用②】

*プロジェクトを利用してみる
プロジェクトの作り方はコマンドライン経由で実施

vue create プロジェクト名
npm run serve

ホットデプロイなので変更内容がリアルタイムで反映される
*フォルダ構成はこんな感じ

ファイル名 概要
favicon.ico アイコンファイル
index.html デフォルトのWEBページ用HTMLファイル
main.js アプリケーションのプログラム
App.vue アプリケーションで使うコンポーネントファイル
logo.png ロゴのイメージファイル
HelloWorld.vue コンポーネントファイル

vueJSのフォルダ構成 (1).png

picture.jpeg

*それぞれのファイルについて

・index.html
appタグに対してjsで操作を行っていく

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width,initial-scale=1.0">
    <link rel="icon" href="<%= BASE_URL %>favicon.ico">
    <title>07-project</title>
  </head>
  <body>
    <noscript>
      <strong>We're sorry but 07-project doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
    </noscript>
    <div id="app"></div>
    <!-- built files will be auto injected -->
  </body>
</html>

・main.js
[マウントについて]
elプロパティがない → 手動でマウントする必要がある
$mount('app') → id="app"のタグにVueのオブジェクトをマウントして利用している

[vueコンポーネントのインポートについて]
import App from './App.vue'

import Vue from 'vue'
import App from './App.vue'

Vue.config.productionTip = false

new Vue({
  render: h => h(App),
}).$mount('#app')

・App.vue
[インポート時のデフォルト設定]
export defaultはスクリプトファイルをimportでインポートしたとき、デフォルトで用意されるものを指定

export default {

}

[タイトルの変更]
change title
App.vueのdoActionから入力された内容(this.message = input)を

<HelloWorld v-bind:title="message"
子コンポーネントのtitle変数に引き渡す

<template>
表示するタグを記載
</template>
<script>
タグの動作を定義したjavascriptを記載
</script>
<style>
レイアウトの内容を記載
</style>
<template>
  <div id="app">
    <HelloWorld v-bind:title="message" v-on:result-event="appAction"/>
    <hr>
    <p>{{result}}</p>
    <button v-on:click="doAction">change title</button>
  </div> 
</template>

<script>
import HelloWorld from './components/HelloWorld.vue'

export default {
  name: 'app',
  components: {
    HelloWorld
  },

  data: function(){
    return {
      message:'HELLO',
      result:'no event'
    }
  },

  methods:{
    appAction: function(message){
      this.result = '(*** you send:"' + message + '".***)'
    }
  },

  methods:{
    doAction:function(){
      var input = prompt("new title:"); // 小さい画面を表示して情報を受け取る
      this.message = input;
    }
  }
}
</script>

<style>
#app {
  font-family: 'Avenir', Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>

・HelloWorld.vue
[プロパティの指定]
props: {
title : String,
}

[データの設定]
data:function(){
return{
};
}

[クリックしたらinputの内容を書き換える]

Click

[の表示]
this.$emit('result-event', this.input);
result-eventが定義されている親のタグにインプットされた内容を引き渡す

<template>
  <div class="hello">
    <h1>{{title}}</h1>
    <p>{{message}}</p>
    <hr>
    <div>
      <input type="text" v-model="input">
      <button v-on:click="doAction">Click</button>
    </div>  
  </div>
</template>

<script>

export default {
  name: 'HelloWorld',
  props: {
    title : String,
  },

  data:function(){
    return{
      message: 'お名前は?',
      input:'no name',
      title:'HELLO'
    };
  },

  methods:{
    doAction: function(){
      this.message = 'こんにちは、' + this.input + 'さん' ;
      this.$emit('result-event', this.input);
    }
  }
}
</script>

<style>
div {
  margin:0px;
  padding: 0px;
  text-align:left;
}
h1 {
  font-size:72pt;
  font-weight:bold;
  text-align:right;
  letter-spacing:-8px;
  color:#f0f0f0;
  margin:0px;
}
p {
    margin:0px;
    color:#666;
    font-size:16pt;
}
</style>
0
0
0

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
0
0