Vue.jsに至る道（Native, jQuery, Vue.js書き比べ）


JS周りが混沌とする中、自分用のメモ。結局わかりにくくなってしまったが、個人用ということでお許しを。

## Native, jQuery, Vue.jsで同じことを書いてみる

### 試したいことは

* HTML内のテキスト取得
* inputの値の取得
* classの編集
* イベント処理

と言ったところ。
Vue.jsは順番を追って書きづらい（Vue.jsが使いづらいという意味ではない）。

### 動作イメージ

下記のような感じのものが表示されるはず。

![スクリーンショット 2018-10-09 12.52.09.png](https://qiita-image-store.s3.amazonaws.com/0/55188/76cdbf72-8d89-45ac-33ca-9536f10b7548.png)



### コードを書く

あと、別に\<script></script>分ける必要ないのだけど、わかりやすさのために分けました。


```html
<!doctype html>
<html>

<head>
    <meta charset="utf-8">
    <title>test</title>
    <style>
        /* 切り替え用のCSS */
        .red{
            color: red;
        }
        .blue{
            color: blue;
        }
        .green{
            color:green;
        }
    </style>
</head>

<body>

    <div>
        <h3></h3>
        <!-- native -->
        <div id="native">
            <p id="native_text">Nativeさん。こんにちは。</p>
            <p><input type="text" value="native" id="native_input"></p>
            <p><button id="native_button">native</button></p>
        </div>
        <!-- jQuery -->
        <div id="jquery">
            <p id="jquery_text">jQueryさん。こんにちは。</p>
            <p><input type="text" value="jquery" id="jquery_input"></p>
            <p><button id="jquery_button">jQuery</button></p>
        </div>
        <!-- vuejs -->
        <div id="vuejs">
            <p id="vuejs_text" v-bind:class="className">{{ message }}</p>
            <p><input type="text" value="vuejs" id="vuejs_text" v-model="vuejs_input"></p>
            <p><button id="vuejs_button" v-on:click="vuejs_click">Vue.js</button></p>
        </div>
    </div>

    <script src="https://code.jquery.com/jquery-3.3.1.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.5.17/dist/vue.js"></script>
    <script>
        //Native
        (function(){
            //値の取得（普通の要素）
            var element1 = document.getElementById("native_text");
            console.log(element1.textContent);
            //値の取得（input）
            var element2 = document.getElementById("native_input");
            console.log(element2.value);
            //classをいじる
            element1.classList.add("red");
            //イベント
            document.getElementById("native_button").addEventListener("click", function(){
                alert("native");
            });
        })();
    </script>
    <script>
        //jQuery
        $(function(){
            //値の取得（普通の要素）
            var text1 = $("#jquery_text").text();
            console.log(text1);
            //値の取得（input）
            var text2 = $("#jquery_input").val();
            console.log(text2);
            //classをいじる
            $("#jquery_text").addClass("blue");
            //イベント
            $("#jquery_button").click(function(){
                alert("jquery");
            });
        });
    </script>
    <script>
        //Vue.js
        var app = new Vue({
            el: "#vuejs",
            data: {
                message: "Vue.jsさん。こんにちは",
                className: "green",
                vuejs_input: "vuejs"
            },
            methods : {
                vuejs_click : function(){
                    alert("vuejs");
                }
            }
        })
    </script>
</body>

</html>
```

## おまけ

### React

同じHTML内に書ききれない（Vueがシンプルってことかな）。
素の状態だと、input毎にonChange書かないと行けなかったり・・・しんどい。
Reactは

* 何をするにもJSXで書く
* 共通のデータはstateで管理
* stateはsetState()で書き換える（でしか、書き換えられない）
* inputではvalueと紐付けるが、onChangeイベントでゴニョゴニョ（値のマップと再描画）しないと動かない

Vueに慣れてるとちょっとしんどい。

```html
<!doctype html>
<html>

<head>
    <meta charset="utf-8">
    <title>react test</title>
    <script src="https://unpkg.com/react@16/umd/react.development.js"></script>
    <script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
    <script src="https://unpkg.com/babel-standalone@6.15.0/babel.min.js"></script>
</head>
<style>
    .purple{
        color: purple;
    }
</style>
<body>
    <div id="root"></div>
    <script type="text/babel">
    (()=>{

        class ReactForm extends React.Component{

            constructor(){
                super();
                this.state = {
                    data: {
                        name: ''
                    }
                };
                this.send = this.send.bind(this);
                this.inputChange = this.inputChange.bind(this);
            }

            inputChange(event){

                var data = this.state.data;

                switch(event.target.name){
                    case 'name':
                        data.name = event.target.value;
                        break;
                    default:
                        break;
                }
                
                this.setState({
                    data: data
                });

            }

            send(event){
                event.preventDefault();
                console.log(this.state.data.name);
                alert("react");
            }

            render(){
                return (
                    <form>
                        <input type="text" name="name" value={this.state.data.name} onChange={this.inputChange}/>
                        <button onClick={this.send}>送信</button>
                    </form>
                );
            }
        }

        function Greeting(props){
            return (
                <p className={props.color}>Reactさん。こんにちは</p>
            );
        }
        
        ReactDOM.render(
            <React.Fragment>
                <Greeting color="purple"/>
                <ReactForm/>
            </React.Fragment>,
            document.getElementById('root')
        );

    })();
    </script>
</body>
```

## 参考

* https://www.aura-office.co.jp/blog/js-native/