LoginSignup
2
3

More than 3 years have passed since last update.

v-modelで色々やってみた

Posted at

v-modelとは

Vue公式ドキュメントより

form の input 要素 や textarea 要素、 select 要素に双方向 (two-way) データバインディングを作成するには、v-model ディレクティブを使用することができます。それは、自動的に入力要素のタイプに基づいて要素を更新するための正しい方法を選択します。ちょっと魔法のようですが、v-model はユーザーの入力イベントにおいてデータを更新するための基本的な糖衣構文 (syntax sugar) で、それに加えて、いくつかのエッジケースに対しては特別な配慮をしてくれます。

すごく魅力的なことが書いてあります。

  • v-modelを使用することでVueのオブジェクトと入力フォームが関連付けられる
  • 入力された内容をVueのオブジェクトに自動反映できる
  • 指定した入力フォームに応じて適した値が反映される (※これがすごく便利)

よし!実装してみよう!!

textarea

v-modelのバインド先には、textareaに入力した内容が反映されます

    <div id="textarea">
        <p>自由に感想を書いてください</p>
        <textarea name="whatFelt" :cols="getMaxCol" :rows="getRowCnt" v-model="message"></textarea>
    </div>
    let textarea = new Vue({
        el:'#textarea',
        data:{
            message:""
        },
        computed: {
            // 横幅を求めます
            getMaxCol:function(){
                let lines = this.message.split(/\n/)
                let maxColLines = lines.reduce((pre,post) => {return pre.length >= post.length ? pre: post})
                console.log(maxColLines)
                return maxColLines.length >= 20 ? maxColLines.length: 20
            },
            // 行数を求めます
            getRowCnt:function(){
                let lines = this.message.split(/\n/)
                return lines.length > 0 ? lines.length : 1
            }
        },
    })

radio

v-modelのバインド先は選択結果が同期されます。

    <div id="radio">
        <p>どのお飲み物になさいますか?</p>
        <template v-for="item in radioList">            
            <input type="radio" name="item.name" id="item.id" v-model="picked" :value="item">
            <label for="item.id">{{item.name}}</label>
        </template>
        <p>注文内容:<span>{{getResult}}</span></p>
    </div>
    let radioList = new Vue({
        el:'#radio',
        data:{
            picked:undefined,
            radioList:[
                {id:1,name:'アイスコーヒー'},
                {id:2,name:'タピオカ'},
                {id:3,name:'なんかのスムージー'},
                {id:4,name:'オレンジジュース'},
            ]
        },
        computed: {
            getResult:function(){
                return this.picked ? this.picked.name: "お冷で!"
            }
        },
    })

select

v-modelのバインド先は選択結果が同期されます

    <div id="select">
        <p>お使いの機種はどちらでしょうか?</p>
        <select name="typeOfPhone" id="typeOfPhone" v-model="selected">
            <template v-for="item in selectList">
                <option>{{item.name}}</option>
            </template>
        </select>
        <p>結果:<span>{{getResult}}</span></p>
    </div>
    let selectList = new Vue({
        el:'#select',
        data:{
            selected:"",
            selectList:[
                {name:'ガラケー'},
                {name:'iPhone'},
                {name:'Android'},
                {name:'PHS'},
                {name:'黒電話'},
            ]
        },
        computed: {
            getResult:function(){
                return this.selected === "" ? "なし" : this.selected
            }
        },
    })

checkbox

v-modelのバインド先は、各項目が選択済みかどうか(value=true/false)が同期されます。

    <div id="checkBox">
        <p>どの動物が好き??</p>
        <template v-for="item in checkList">
            // v-modelでitemの項目として定義されているvalueがひも付きます
            // ※itemの項目として定義されていない場合、暗黙的に追加されていそうです
            <input type="checkbox" name="item.name" id="item.id" v-model="item.value">
            <label for="item.id">{{item.name}}</label>
        </template>
        // computedを利用して動的に結果を表示
        <p>結果:<span>{{getResult}}<span></p>
    </div>
    let checkBox = new Vue({
        el:'#checkBox',
        data:{
            checkList:[
                {id:1,name:'ネッコ',value:false},
                {id:2,name:'イッヌ',value:false},
                {id:3,name:'サッル',value:false},
                {id:4,name:'トッリ',value:false},
            ],
        },
        computed: {
            getResult:function(){
                let message = 'わたしが好きなのは・・・'
                // 選択済みの項目を抽出
                let list = this.checkList.filter((item,index)=>item.value)
                if(list.length === 0){
                    return "未選択"
                }else{
                    for(let item of list){
                        console.log(item.value)
                        message += item.value ? item.name + " " : ""
                    }
                    return message
                }
            }
        },
    })
2
3
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
2
3