[Vue.js] 一下子就搞懂Vue.js在做什麼的範例程式碼

Know what Vue.js does in ten minite

前言

身為曾經的AngularJS開發者,歷經Angular轉型成框架的學習,到了接觸Vue.js

我非常認同Vue.js作者的理念和Vue.js的特性

上圖有提到MVVM,這邊順道提一下MVVM幾個特性

※下述資料指的是Javascript的資料,例如:物件、變數、集合陣列…等等

單向綁定:由JS指派DOM元素資料,再由DOM元素顯示資料,通常資料會綁定DOM元素的Attribute,例如Vue.js的v-bind指令,也可能資料直接顯示,例如Vue.js的雙大刮號運算式

雙向綁定:除了從JS指派資料給DOM元素之外,由於經常綁定表單欄位<input>、<select>、<textarea>讓使用者輸入,而且輸入的資料會自動寫回JS端,故稱為雙向綁定。在Vue.js裡,使用v-model指令來雙向綁定表單欄位。

 

官網說明與範例:表單輸入綁定

如果我的網站畫面只有兩、三個頁面需要MVVM,卻使用Angular這麼龐大的框架,其他畫面都是ASP.net的View,卻只有那兩、三個MVVM頁面是Angular的畫面然後搭配Web API存取資料

自己都覺得殺雞用牛刀Orz,也沒有一致性,相比之下Angular的前身AngularJS因為是函式庫反而還比較好用

不過AngularJS由於效能問題(例如:呼叫$scope.$apply() ),加上現在Google主力開發Angular框架想愈做愈大,AngularJS的生命週期顯得衰落就像元祖級的Knockout.js

Vue.js官網說明:对比其他框架 AngularJS (Angular 1)

此時想找一個替代AngularJS的函式庫:簡單好學好上手,程式碼短少又淺顯易懂,可以快速整合至現有網站

Vue.js是一個不錯的選擇,而且2017~2018年,它在GitHub上的獲星數都是第一名

我自己很看好這套函式庫的潛力(應該可以再戰兩、三年,因為我花一個晚上就學完官網一半文件,真的簡單又好用)

而且是華人開發的前端技術,大家可以多多支持一下,讓世界瞧瞧華人的力量XD

不過

不是任何頁面都適合MVVM開發方式,何時需要MVVM?以下是我站在開發效率考量的見解  

1.畫面動態新增、刪除表單輸入欄位,並且想將那些動態產生出來的欄位連同User輸入資料向Server端儲存

2.用戶輸入表單資料時或用戶刪除畫面上的DOM元素時,DOM元素要即時和資料連動變更(這也是MVVM綁定數據的開發方式最有價值之處,尤其是雙向綁定)

例如以下的圖片上傳預覽圖:(曾經上架手機App到Google Play和App Store的人應該熟悉這種UI)

當時開發此網頁我採用jQuery來處理↓,紅框處就是jQuery顯得弱勢的地方:不但要處理資料,也要手動自己管理畫面上的DOM元素

↑如果採用MVVM開發方式,只要專心處理資料就好,不必再額外花心思擔心資料一變、畫面該怎麼變動。

3.使用網頁技術開發手機App,例如:Cordova、PhoneGap,因為手機App就是典型MVVM的體現,這時用jQuery反而程式碼囉嗦冗長

4.承上一點,你要開發的功能有不得已原因,不能表單提交,必須重度依賴Ajax,例如:表單存在bootstrap Modal裡、或Facebook那種SPA(Single Page Application)網站

5.jQuery使用過多的before()、after()、prepend()、append()、html()、text()方法給DOM元素動態指派html內容,造成組太多html字串不好維護

剩下的…我覺得明明是簡單畫面,原本可用少許程式碼快速開發完成並滿足客戶需求的功能,若硬要把MVVM整合進網頁中,反而可能多寫很多前端JavaScript代碼拖慢開發速度

我不知道那些人是不是看不懂團隊趕工趕時間的氣氛,還是自私只為了滿足自己玩新技術的私慾、抑或覺得前端框架現在超熱門很潮於是無腦地大量使用.....

本人親身體驗過這種豬隊友,所以話才說得重

舉例:網頁登入畫面需不需要採取MVVM開發?

我會回答根本不需要,直接表單submit至網站後端處理,後端判斷帳密正確就在後端直接Redirect至其它頁面,帳密不正確就回傳原本的View,並輸出錯誤訊息

除非登入表單被放在類似Bootstrap的Modal Dialog裡,表單一提交,網頁就會刷新,Modal Dialog就會不見,必須採用Ajax呼叫後端的情況

這時候採用 jQuery的$("form").serialize();用法,雖然可以一口氣把表單輸入參數傳遞出去

 
let myForm =$("form").serialize(); //表單輸入參數序列化成QueryString
$.ajax({ 
        url: "url",
        method: "post",
        data: myForm, 
        success: function (result) {
           console.log(result);     
        }
       });//End ajax

但Vue.js也不是省油的燈,它直接傳遞物件給後端就行了,這種情況就難分高下XD


                    <form class="form-row">
                        <div class="col-3">
                            <input type="text" class="form-control" v-model="user.account" name="useranme" placeholder="請輸入帳號" />
                        </div>
                        <div class="col-3">
                            <input type="password" class="form-control" v-model="user.pd" name="pd" placeholder="請輸入密碼" />
                        </div> 
                        <div class="col-2">
                            <button class="btn btn-info" type="button" v-on:click="loginFunc">模擬登入</button> 
                        </div>
                        <div class="col-4">
                            <div v-text="loginResult"></div>
                        </div>
                       
                    </form>
  let app = new Vue({
            el: '#myApp',/*定義Vue作用範圍,el指的是element*/
            data: {//data是關鍵字 
                user: { //登入物件
                    account: "",
                    pd:""
                },
                loginResult:"" //登入結果
            },
            methods: { //methods是關鍵字 
                loginFunc: function () {
                    let vm = this;
                    $.ajax({
                        url: "@Url.Action("Login", "Home")",
                        method: "post",
                        data: vm.user, //直接傳遞物件
                        success: function (text) {
                            vm.loginResult=text;//畫面顯示登入結果
                        }
                    });
                } 
                
            }
        });//end new Vue
   [HttpPost]
   public IActionResult Login(string account,string pd)
   {

      return Content($@"您的登入帳密為 {account} / {pd}");
   }
   

Vue.js 簡介

Vue.js 是近兩、三年熱門的前端Javascript框架之一,它是一套以操作資料狀態來管理畫面的MVVM架構函式庫。 

由於MVVM雙向綁定的好處,讓開發人員專注在Javascript資料的操作而不用花費心思管理維護畫面Html的DOM元素,因此相比jQuery減少很多操作DOM元素程式碼。

加上學習成本低很好入門、它很有彈性可以寫得簡單也可以應付複雜架構的Web應用程式,並且擁有豐富中文資源的支持等等特性

更在2017、2018年的GitHub上蟬聯Javascript框架獲星數第一名,未來發展潛力不容小覷。

起手式程式碼

下面的範例程式碼是我花了一個晚上學習Vue.js,去蕪存菁後寫下來的筆記,Vue.js 2.x版

說明都在註解裡,剛入門只需要認識下面Sample Code的 v-* 指令,Vue.js這個函式庫差不多就可以運用在工作上 

<!doctype html>
<html lang="en">
<head>
    <!-- Required meta tags -->
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

    <!-- Bootstrap CSS -->
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/css/bootstrap.min.css" integrity="sha384-GJzZqFGwb1QTTN6wy59ffF1BuGJpLSa9DkKMp0DgiMDm4iYMj70gZWKYbI706tWS" crossorigin="anonymous">

    <title>Vue.js的起手式範例程式碼</title>
    <style type="text/css">
        body {
        padding-top:30px;
        }
    </style>
</head>
<body> 
    <div class="container">
        <div class="row">
            <div class="col-12">
                <!--自己隨便取一個DOM ID,此容器內將是Vue App的作用範圍-->
                <div id="myApp"> 
                    {{ message }} <!--直接顯示資料message-->
                    <div v-text="message"></div> <!--v-text單向綁定資料message,效果和上面一樣都是當做純文字顯示-->
                    <div v-html="message"></div> <!--v-html單向綁定資料message,以html方式顯示-->
                    <hr />
                    <ul v-if="init_users.length>0">
                        <!--使用v-for跑迴圈-->
                        <li v-for="(user , index) in init_users" v-text="(user.username+' '+user.email)"></li>
                    </ul>
                    <hr />
                    <!--使用v-on監聽JS事件-->
                    <button class="btn btn-primary" v-on:click="MyAjaxFunction">發出Ajax</button>
                    <ul v-if="users.length>0">
                        <!--如果users集合有資料才渲染<ul>元素,否則移除-->
                        <!--使用v-for跑迴圈-->
                        <li v-for="(user , index) in users">
                            <!--v-bind專門單向綁定DOM元素的Attribute-->
                            <a href="#" v-bind:title="user.email" v-text="user.username"></a>
                        </li>
                    </ul>
                    <hr />
                    <!--單獨一個checkbox,打勾不打勾,值會自動為true or false-->
                    <div class="custom-control custom-checkbox">
                        <!--使用v-model為表單欄位<input>、<select>、<textarea>做雙向綁定-->
                        <input type="checkbox" class="custom-control-input" name="myCheckBox" id="myCheckBox" v-model="isChecked" />
                        <label class="custom-control-label" for="myCheckBox">點擊我</label>
                    </div>
                    <div v-if="isChecked===true" v-text="(msg+' 渲染 by v-if')"></div> <!--v-if如果為true就渲染此DOM元素,否則從畫面上移除DOM元素-->
                    <div v-show="isChecked===true" v-text="(msg+' 顯示 by v-show')"></div> <!--v-show如果為true就顯示此DOM元素,否則display:none;隱藏-->
                    <hr />
                    <!--多個checkbox,必須給值,打勾不打勾,由值決定-->
                    <div class="custom-control custom-checkbox">
                        <!--多個checkbox,必須雙向綁定集合陣列-->
                        <input type="checkbox" class="custom-control-input" name="myCheckBox1" id="myCheckBox1" value="碼農" v-model="jobs" />
                        <label class="custom-control-label" for="myCheckBox1">碼農</label>
                    </div>
                    <div class="custom-control custom-checkbox">
                        <!--使用v-model為表單欄位<input>、<select>、<textarea>做雙向綁定-->
                        <input type="checkbox" class="custom-control-input" name="myCheckBox2" id="myCheckBox2" value="打字員" v-model="jobs" />
                        <label class="custom-control-label" for="myCheckBox2">打字員</label>
                    </div>
                    <div class="custom-control custom-checkbox">
                        <!--使用v-model為表單欄位<input>、<select>、<textarea>做雙向綁定-->
                        <input type="checkbox" class="custom-control-input" name="myCheckBox3" id="myCheckBox3" value="工程師" v-model="jobs" />
                        <label class="custom-control-label" for="myCheckBox3">工程師</label>
                    </div>
                    <div>
                        您的職業勾選了:
                        <!--如果jobs集合有資料才渲染<ul>元素,否則移除-->
                        <ul v-if="jobs.length>0">
                            <li v-for="(job ,index) in jobs" v-text="job"></li>
                        </ul>
                    </div>
                    <hr />

              <div class="custom-control custom-radio">
                  <input type="radio" class="custom-control-input"  id="userSexMale" name="Sex" value="男" v-model="Sex" />
                  <label class="custom-control-label" for="userSexMale">男</label>
               </div>
               <div class="custom-control custom-radio">
                 <input type="radio" class="custom-control-input"  name="Sex" id="userSexFemale"  value="女" v-model="Sex" />
                 <label class="custom-control-label" for="userSexFemale">女</label>
			   </div>
               <div>
				  你的性別是: {{ Sex }}
			   </div>
				  <hr />
                    <!--此區塊將使用Ajax方式登入-->
                    <form class="form-row">
                        <div class="col-3">
                            <input type="text" class="form-control" v-model="user.account" name="useranme" placeholder="請輸入帳號" />
                        </div>
                        <div class="col-3">
                            <input type="password" class="form-control" v-model="user.pd" name="pd" placeholder="請輸入密碼" />
                        </div>
                        <div class="col-2">
                            <button class="btn btn-info" type="button" v-on:click="loginFunc">模擬登入</button>
                        </div>
                        <div class="col-4">
                            <!-- 登入結果-->
                            <div v-text="loginResult"></div>
                        </div>
                    </form>
                    <hr />
                    <button class="btn btn-info" id="btnGetDataFromVue">從jQuery取得Vue App的資料</button>
                    <div id="divJQueryResult"></div>
                    <hr />
                    <button class="btn btn-info" id="btnCallVueFunc">從jQuery呼叫Vue App的function</button>
                    <!--顯示jqText的資料-->
                    <div v-text="jqText"></div>
                    <hr />
                    <div>
                        <!-- 事件修飾符prevent:https://cn.vuejs.org/v2/guide/events.html#%E4%BA%8B%E4%BB%B6%E4%BF%AE%E9%A5%B0%E7%AC%A6-->
                        <a href="https://www.google.com.tw" v-on:click.prevent="a_Func">Google超連結</a>
                    </div>
                    <form action="/Home/Vue" method="post">
                        <!--.prevent修飾符也可以阻止submit預設提交行為-->
                        <input type="submit" class="btn btn-primary" value="提交" v-on:click.prevent="a_Func" />
                    </form>
                </div>
            </div>
        </div>
    </div>


    <!-- jQuery first, then Popper.js, then Bootstrap JS -->
    <script src="https://code.jquery.com/jquery-3.3.1.min.js" crossorigin="anonymous"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.6/umd/popper.min.js" integrity="sha384-wHAiFfRlMFy6i5SRaxvfOCifBUQy1xHdJ/yoi7FRNXMRBu5WHdZYu1hA6ZOblgut" crossorigin="anonymous"></script>
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/js/bootstrap.min.js" integrity="sha384-B0UglyR+jN6CkvvICOB2joaf5I4l3gm9GU6Hc1og6Ls7i6U/mkkaduKaBhlAXv9k" crossorigin="anonymous"></script>
    <!-- 引用Vue.js -->
    <script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.js"></script>
    <script type="text/javascript"> 
        //let init_users = @Html.Raw(ViewData["users"]); //我使用的是ASP.net Core 2.1實作範例,才會有此@Html.Raw(ViewData["users"])玩意兒
        //let loginUrl = "@Url.Action("Login", "Home")";//@@Url.Action也是ASP.net Core 2.1 Razor View的東西,和Vue.js無關
          let loginUrl = "/Home/Login";//模擬登入的Url



        //假裝這是後端預先準備的Json資料
        let init_users = [
            {
                "id": 1, 
                "username": "Bret",
                "email": "Sincere@april.biz" 
            },
            {
                "id": 2, 
                "username": "Antonette",
                "email": "Shanna@melissa.tv" 
            }];
        let app = new Vue({
            el: '#myApp',/*定義Vue作用範圍,el指的是element,此屬性必填*/
            data: {//data是關鍵字
                message: `<a href="#">Hello Vue!</a>`,
                msg: "我被打勾",
                users: [],
                mydata: "from vue",
                isChecked: false,
                jobs: ["工程師"],//預設多個checkbox當中,會事先打勾工程師的項目,如果這裡預設jobs集合裡都沒有給值的話,網頁一載入剛開始的多個checkbox就都不會打勾
                Sex :"",
                init_users: init_users,//假裝把後端資料指派給init_users data
                jqText: "",//到時候會顯示從jQuery叫用的文字
                user: { //登入發出Ajax要用的物件
                    account: "",
                    pd:""
                },
                loginResult:""//登入結果
            },
            methods: { //methods是關鍵字,通常處理和用戶的互動事件,底下function,不可使用()=>箭頭函式宣告,否則this指向的對象是錯誤的
                MyAjaxFunction: function () {
                    let vm = this;//this指的是app變數,也可以當做ViewModel

                    $.ajax({ //Vue.js不像Angular內建Ajax API,Vue.js也並不限制使用哪個ajax框架,所以可以借用jQuery Ajax來呼叫
                        url: "https://jsonplaceholder.typicode.com/users", 
                        method: "get",
                        //data: { mydata: vm.mydata }, //也可以把ViewModel的資料送到後端
                        dataType: "json",//上面網址回傳json格式資料
                        success: function (users) {
                            vm.users = users; //AngularJS還得額外呼叫$scope.apply();來套用ViewModel的變更,Vue.js則不用
                        }
                    });
                },
                loginFunc: function () {//登入
                    let vm = this;
                    /*$.ajax({
                        url: loginUrl,
                        method: "post",
                        data: vm.user,//直接傳遞ViewModel的物件
                        success: function (text) {
                            vm.loginResult=text;
                        }
                    });*/
                    vm.loginResult = `您輸入的帳密為 ${vm.user.account} / ${vm.user.pd}`;
                },
                a_Func: function () {
                    /*v-on:click.prevent*/
                    /*prevent修飾符用途和jQuery的preventDefault()一樣,防止預設行為發生*/
                    /*另外也有表單輸入綁定的修飾符也不錯用:https://cn.vuejs.org/v2/guide/forms.html#%E4%BF%AE%E9%A5%B0%E7%AC%A6 */

                    /*此function要寫什麼code,自由料理*/

                },
                MyVueFunction: function (text)
                {
                    this.jqText = text; //從jQuery指派給Vue App的資料
                }
            }
        });


        /*以下是jQuery的世界*/
        $(function () {
            $("#btnGetDataFromVue").on("click", function ( ) {
                let message = app.message;//取得ViewModel的資料
                $("#divJQueryResult").html(message);
            });
            $("#btnCallVueFunc").on("click", function () {
                //呼叫Vue.js的function
                app.MyVueFunction("來自jQuery的字串");  
            });
        });
    </script>
</body>
</html>

線上Demo:https://jsfiddle.net/ShadowKao/5f8417n6/

其中 el 參數必填而且不建議Vue的作用範圍掛載到<html>、<body>的DOM元素:https://cn.vuejs.org/v2/api/#el

注意data裡的變數名稱最好不要使用 $ 或 _ 底線開頭,例如:$yourProperty、_yourProperty,因為有可能和Vue.js的內建屬性、API有衝突

留意雙大括號的模板語法:

1.只能顯示純文字,無法顯示html

2.限制請見官網 ↓

雖然不能在雙大括號裡 宣告變數、if 判斷、for 迴圈,但你可以將這些放在 computed 計算屬性,例如: 時間處理

 

 

※2019.01.19追記

{{ message }}  這種寫法有可能使用者第一次載入網頁或按下Ctrl+F5時,會直接看到原始碼,整理兩種解法↓

<!doctype html>
<html>
<head>
    <!-- Required meta tags -->
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

    <!-- Bootstrap CSS -->
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/css/bootstrap.min.css" integrity="sha384-GJzZqFGwb1QTTN6wy59ffF1BuGJpLSa9DkKMp0DgiMDm4iYMj70gZWKYbI706tWS" crossorigin="anonymous">

    <title>Hello, Vue.js!</title>
    <style type="text/css">
        body {
            padding-top: 30px;
        } 

        /*使用v-cloak記得先定義CSS*/
        [v-cloak] {
            display: none !important;
        }
    </style>
</head>
<body>
    
    <div class="container" id="myApp">
        <div class="row">
            <div class="form-group col-12">
                {{ message }} <!--用戶第一次載入網頁或 Ctrl+F5 時,可能會先看到原始碼-->
            </div>
            <div class="form-group col-12" v-text="message">  <!--如果資料內容是html,則使用v-html-->
            </div>
            <div class="form-group col-12" v-cloak>  <!--如果容器內有其他DOM元素狀況,用v-cloak --> 
                <input type="text" placeholder="請輸入" /> {{message}}
            </div>
        </div>
        </div>


    <!-- jQuery first, then Popper.js, then Bootstrap JS -->
    <script src="https://code.jquery.com/jquery-3.3.1.min.js" crossorigin="anonymous"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.6/umd/popper.min.js" integrity="sha384-wHAiFfRlMFy6i5SRaxvfOCifBUQy1xHdJ/yoi7FRNXMRBu5WHdZYu1hA6ZOblgut" crossorigin="anonymous"></script>
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/js/bootstrap.min.js" integrity="sha384-B0UglyR+jN6CkvvICOB2joaf5I4l3gm9GU6Hc1og6Ls7i6U/mkkaduKaBhlAXv9k" crossorigin="anonymous"></script>
    <!-- 引用Vue.js -->
    <script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.js"></script>
    <script type="text/javascript">
 
        let myApp= new Vue({
            el: '#myApp',/*定義Vue作用範圍,el指的是element*/
            data: { //data是關鍵字
                message:"Hello Vue!!"  
            } 
        }); 
    </script>
</body>
</html>

線上Demo:https://jsfiddle.net/ShadowKao/fohyzec5/

關於v-model的.number修飾符,用途在當使用者輸入時,會自動把輸入的字串轉型成Number型別,如果轉型失敗,則當做字串型別

<!doctype html>
<html  >
<head>
    <!-- Required meta tags -->
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

    <!-- Bootstrap CSS -->
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/css/bootstrap.min.css" integrity="sha384-GJzZqFGwb1QTTN6wy59ffF1BuGJpLSa9DkKMp0DgiMDm4iYMj70gZWKYbI706tWS" crossorigin="anonymous">

    <title>Hello, Vue.js!</title>
    <style type="text/css">
        body {
            padding-top: 30px;
        }  
    </style>
</head>
<body> 
    <div class="container" id="myApp">
        <div class="row">
            <div class="form-group col-12">
                <label>不加修飾符.number,試試輸入1234,會被當做字串</label>
                <input type="text" v-model="age" name="age" placeholder="請輸入數字或字串" class="form-control" /> <br />
                <label>
                    試試輸入一般字串,修飾符v-modal.number轉型失敗時,會當做字串型別
                </label>
                    <input type="text" v-model.number="age" name="age" placeholder="請輸入數字或字串" class="form-control" />
            </div>
            <div class="form-group col-12" v-text="`型別:${typeof(age)}:內容:${age}`">
            </div>
            </div>
        </div>


    <!-- jQuery first, then Popper.js, then Bootstrap JS -->
    <script src="https://code.jquery.com/jquery-3.3.1.min.js" crossorigin="anonymous"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.6/umd/popper.min.js" integrity="sha384-wHAiFfRlMFy6i5SRaxvfOCifBUQy1xHdJ/yoi7FRNXMRBu5WHdZYu1hA6ZOblgut" crossorigin="anonymous"></script>
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/js/bootstrap.min.js" integrity="sha384-B0UglyR+jN6CkvvICOB2joaf5I4l3gm9GU6Hc1og6Ls7i6U/mkkaduKaBhlAXv9k" crossorigin="anonymous"></script>
    <!-- 引用Vue.js -->
    <script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.js"></script>
    <script type="text/javascript">
 
        let app = new Vue({
            el: '#myApp',/*定義Vue作用範圍,el指的是element*/
            data: {//data是關鍵字
                age: undefined  
            }  
        });
 
    </script>
</body>
</html>

線上Demo:https://jsfiddle.net/ShadowKao/2k9f6har/

覺得記憶這點很麻煩的話,乾脆不要使用修飾符.number,在methods中處理資料的轉型並判斷用戶輸入的值是否轉型成功

至於v-model的另一個修飾符.trim挺實用,請見官網用法↓

關於事件處理函式中獲取$event的注意事項,官網連結:#v-on,官網圖↓


我的測試結果↓

<body> 
    <div class="container" id="myApp">
        <div class="row">
            <div class="form-group col-12">
                <button type="button" class="btn btn-primary" value="doThis1" v-on:click="doThis1">事件不傳參數</button>
                <button type="button" class="btn btn-primary"  value="doThis2" v-on:click="doThis2($event)">事件只傳$event</button>
                <button type="button" class="btn btn-info"  value="doThis3" v-on:click="doThis3('Hello Vue.js!!',$event)">事件傳遞參數和$event</button>
                <button type="button" class="btn btn-info"  value="doThis4" v-on:click="doThis4('Hello Vue.js 2!!')">事件只傳遞參數</button>
            </div> <!-- end .form-group-->
            <div class="form-group col-12">
               觸發事件target.value: {{showData}}
            </div>
            <div class="form-group col-12">
                訊息: {{msg}}
            </div>
        </div> <!--end .row-->
        </div> <!--end .container-->


    <!-- jQuery first, then Popper.js, then Bootstrap JS -->
    <script src="https://code.jquery.com/jquery-3.3.1.min.js" crossorigin="anonymous"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.6/umd/popper.min.js" integrity="sha384-wHAiFfRlMFy6i5SRaxvfOCifBUQy1xHdJ/yoi7FRNXMRBu5WHdZYu1hA6ZOblgut" crossorigin="anonymous"></script>
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/js/bootstrap.min.js" integrity="sha384-B0UglyR+jN6CkvvICOB2joaf5I4l3gm9GU6Hc1og6Ls7i6U/mkkaduKaBhlAXv9k" crossorigin="anonymous"></script>
    <!-- 引用Vue.js -->
    <script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.js"></script>
    <script type="text/javascript">
         
        let app = new Vue({
            el: '#myApp',
            data: {
                showData: "",
                msg: ""
            },
            methods: { //methods是關鍵字,通常處理和用戶的互動事件
                doThis1: function ($event) {
                    //事件監聽沒傳遞$event,但可透過注入方式取得
                    let vm = this;
                     
                    vm.showData = $event.target.value;
                    vm.msg = "";
                },
                doThis2: function ($event) {
                    //一目瞭然的寫法
                    let vm = this;
                    vm.showData = $event.target.value;
                    vm.msg = "";
                },
                doThis3: function (msg, $event) {
                    //一目瞭解的寫法
                    let vm = this;
                    vm.showData = $event.target.value;
                    vm.msg = msg;
                },
                doThis4: function (msg, $event) {
                    //事件監聽當只有傳遞參數時..
                    let vm = this; 
                    
                    vm.showData =typeof( $event);//$event即使注入仍然抓不到
                   
                    vm.msg = msg;
                }
                 
            }  
            

             
        }); 
    </script>
</body>

線上Demo:https://jsfiddle.net/ShadowKao/jx8dozqu/

※ v-on:click="doThis1" 這個取名"事件不傳遞參數"其實怪怪的,正確應該算委派,而Vue.js在背後偷偷傳入$event給事件處理函式

關於$event的結論,如果v-on事件監聽時有傳遞參數的話,必須連同$event也要一起傳遞,才能在事件處理函式獲取$event

2019.1.20 追記:

表單欄位Checkbox,可以利用true-value、false-value來設定當勾不勾選時的值

範例如下:

<!doctype html>
<html>
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <!-- Bootstrap CSS -->
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/css/bootstrap.min.css"
          integrity="sha384-GJzZqFGwb1QTTN6wy59ffF1BuGJpLSa9DkKMp0DgiMDm4iYMj70gZWKYbI706tWS" crossorigin="anonymous">
    <title>Vue.js Checkbox</title>
    <style type="text/css">
        body {
            padding-top: 30px;
        }
        [v-cloak] {
          display:none !important;
        }
    </style>
</head>
<body>
    <div class="container" id="myApp">
        <div class="row">
            <div class="col-12">
        <div class="custom-control custom-checkbox">
   <input type="checkbox" class="custom-control-input"  id="chk1"  name="chk1"  v-model="chk1" />
   <label class="custom-control-label" for="chk1">預設的chekeckbox</label>
             </div>
						 {{chk1}}
						 
						 <hr/>
						 
						 
	 <div class="custom-control custom-checkbox">
   <input type="checkbox" class="custom-control-input" id="chk2"  name="chk2"  v-model="chk2" true-value="yes" false-value="no" />
      <label class="custom-control-label" for="chk2" >調整真假值的chekeckbox</label>
             </div>
						  {{chk2}}
						 
						 <hr/>
            </div>

        </div>
    </div>
      
    <!-- jQuery first, then Popper.js, then Bootstrap JS -->
    <script src="https://code.jquery.com/jquery-3.3.1.min.js" crossorigin="anonymous"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.6/umd/popper.min.js" integrity="sha384-wHAiFfRlMFy6i5SRaxvfOCifBUQy1xHdJ/yoi7FRNXMRBu5WHdZYu1hA6ZOblgut" crossorigin="anonymous"></script>
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/js/bootstrap.min.js" integrity="sha384-B0UglyR+jN6CkvvICOB2joaf5I4l3gm9GU6Hc1og6Ls7i6U/mkkaduKaBhlAXv9k" crossorigin="anonymous"></script>
    <!--引用Vue.js-->
    <script type="text/javascript" src="https://vuejs.org/js/vue.js"></script>
    <script type="text/javascript">
        /*Vue.js以操作資料為主*/ 
        let myApp = new Vue({
            el: "#myApp", /*必填*/
            data: {
                chk1:false,
                chk2:"no"
            } 
        });

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

線上Demo:https://jsfiddle.net/ShadowKao/35c1td9m/

 

最後

文章有提到兩點

1.畫面動態新增、刪除表單輸入欄位,並且想將那些動態產生出來的欄位連同User輸入資料向Server端儲存

2.User輸入資料時,要即時和DOM元素連動變化

關於此兩點,日後有空再補上Sample Code (可能同時寫jQuery版本和Vue.js版本,做兩者的比較XD)

認識一下資料綁定、雙向綁定的吸引人之處

有時間的話,應該也會寫寫uploadifive圖片上傳範例的Vue.js版本

由於本文是初心者向,只提到一點點語法基礎當敲門磚,剩下的組件Component、路由、生命周期,還有進階API....

文本就不提了

※吐嘈一下,Component概念在後端的動態網頁技術,例如:ASP.net MVC的PartialView也有,PartialView也能接受傳遞參數,用途、功能幾乎一樣

我應該不會使用Vue.js的Component,因為組html字串當做template在開發時期無法被編譯器檢查錯誤:组件基础

如果你討厭後端組SQL字串來查詢資料庫,那麼你的的想法應該會和我一樣

 

資源參考

Vue.js官網:找文件就在這裡

Class 與 Style 綁定:使用Vue.js操作樣式,本文沒提到的必備入門知識

Chrome瀏覽器的Vue.js除錯用擴充套件:Vue.js devtools,可以在網頁執行時期查看Vue綁定的各種資料

JSONPlaceholder:免費提供線上REST API假資料供開發人員測試的佛心網站