Vue.js入門-1

by vivid 15. 五月 2019 01:43

.NET Magazine國際中文電子雜誌
作 者:許薰尹
審 稿:張智凱
文章編號:N190520702
出刊日期: 2019/5/15

Vue.js是一個開放源碼(Open Source),漸進式框架(Progressive JavaScript Framework),用於開發互動式的網頁使用者操作介面。目前有許多類似的漸進式框架可以簡化前端網頁程式的開發動作,那麼Vue.js有什麼不同呢? Vue.js的特色是專注在使用者檢視層(View),簡單、易用,容易整合到現有的大型專案之中使用。

Vue.js是由前Google工程師尤雨溪(Evan You)發明的,目前加盟阿里巴巴Weex團隊,Vue.js第一個版本是在2014年2月問市,現在已經成為一個非常流行的前端開發框架。

Vue.js提供的特色如下:

  • 輕量型的框架:輕量、且效能好。
  • Vue.js專注在MVVM(Model - View - ViewModel)設計模式中的ViewModel層。
  • 採用虛擬DOM(Virtual DOM),不直接操作DOM,而是建立一個以JavaScript資料結構形式存在的DOM複本,直接對JavaScript資料結構進行異動。所進行的異動稍後會自動更新到真正的DOM,如此將可進行最佳化以提升效能。
  • 提供資料繫結(Data Binding)能力:此功能可以將值關聯到指定的HTML標籤或Attribute,以變更顯示資料或套用樣式。
  • 元件(Component):可以利用元件建立自訂的項目,便可以在HTML網頁中重複地使用。
  • 事件處理:透過簡單的HTML Attribute註冊DOM事件。
  • 動畫效果:可以在DOM物件項目新增、修改時,為HTML項目設定動畫效果。
  • 計算屬性(Computed Properties):可以接聽HTML UI介面中項目的異動,不需要撰寫額外的程式碼,可以進行一些必要的運算。
  • 樣板(Templates):提供以HTML為基礎的樣版,以便將DOM物件繫結到Vue實體(Instance)資料。
  • 指示詞(Directives):內建許多「v-」開頭的指示詞,用來進行程式邏輯的判斷。
  • 監看程式(Watchers):自動監看資料是否有異動。
  • 路由(Routing):用來導覽至其它網頁。

在這篇文章中,將要介紹Vue.js基本使用,從安裝開發環境,到使用Vue.js元件。

開發環境安裝與設定

最簡單的安裝方式便是到官網下載Vue.js相關檔案,首頁在以下網址:「https://vuejs.org/v2/guide/installation.html」。

clip_image002

圖 1:下載Vue.js相關檔案。

在首頁選擇想要下載使用的版本,本文以Vue.js 2.6.10版為例,檔案分為兩種:

  • 「vue.js」:除錯版(Development)的Vue.js函式庫,會包含一些空白字元、除錯資訊等等,在開發階段易於除錯。
  • 「vue.min.js」:發行版(Production)的Vue.js函式庫,會移除一些不必要的空白字元、註解等等,讓檔案最小化,以求上線階段節省下載時間。

雖然不太可能發生,但若無除錯需求,在開發、上線階段都只需在網頁之中引用發行版(vue.min.js)即可,你可以將這個檔案放在網站應用程式專案之中。

接著便可以在HTML網頁之中引用下載下來的檔案,參考以下範例程式碼:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title> Document </title>
</head>

<body>
  <h1> Demo </h1>
  <script src="js/vue.min.js"> </script>
</body>
</html>


使用內容傳遞網路(CDN)

你也可以直接在網頁中,引用內容傳遞網路(Content delivery network或Content distribution network,縮寫:CDN)伺服器上的Vue.js程式庫,以下的連結可以下載到最新版本的Vue.js程式庫:

<script src="https://cdn.jsdelivr.net/npm/vue"></script>

或者參考以下的連結,明確指定想要使用的Vue.js版本:

<script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>

使用NPM下載

除了上述下在Vue.js檔案的方式之外,要安裝Vue.js還可以透過「npm」工具程式來進行下載。「npm」隨著Node.js散發,也就是說只要安裝Node.js就會自動安裝「npm」工具程式。Node.js:下載網址為:「https://nodejs.org/en/」。

clip_image004

圖 2:下載Node.js。

從官網下載適當版本後,進行安裝作業。Node.js安裝完成之後,可以在命令提示字元輸入以下「npm install」指令來安裝Vue.js套件:

npm install vue

這個命令執行結果請參考下圖所示:

clip_image006

圖 3:使用NPM下載並安裝Vue.js。

第一個Vue.js基本範例

我們來看第一個Vue.js基本範例,以了解Vue.js與DOM之間該如何互動,請參考以下範例程式碼:

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title> Document </title>
</head>

<body>
  <div id="divMsg">
    <h1> {{ msg }} </h1>
  </div>
  <script src="js/vue.min.js"> </script>
  <script >
    var vm = new Vue({
      el: '#divMsg',
      data: {
        msg: 'Hello World'
      }
    });
  </script>
</body>

</html>

網頁中的「<div id="divMsg">」標籤使用宣告的方式,將資料更新到DOM,以便在網頁中印出「Hello World」訊息。訊息的顯示採用{{}}語法。接著在程式中,我們使用「new Vue({ })」建立Vue物件實體(Vue Instance),傳入一個Options物件當參數,利用「el」屬性指定DOM元素「#divMsg」,我們將此DOM元素視為容器(Container);「data」屬性設定為一個物件,其「msg」屬性的資料為「Hello World」,並透過{{ msg }}語法,將「Hello World」字串的值,更新到DOM物件「#divMsg」元素之中。這個範例執行結果請參考下圖:

clip_image008

圖 4:Vue.js基本範例執行結果。

Vue實體

每一個Vue應用程式都需要使用Vue函式建立一個Vue實體(Vue Instance),我們稱這個實體為「根Vue實體(root Vue instance)」。依照慣例,這個實體的變數名稱通常稱為「vm」,它是ViewModel的縮寫,當然你可以放心的自訂名稱。當你建立Vue物件實體(Vue Instance),可以傳入一個Options物件當參數,此物件可以定義資料(data)與方法(method),參考以下範例程式碼:

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title> Document </title>
</head>

<body>
  <div id="divMsg">
    <h1> Employee Id : {{ empId }} </h1>
    <h1> Employee Name : {{ empName }} </h1>
    <h1> Employee Info : {{ showInfo() }} </h1>
  </div>
  <script src="js/vue.min.js"> </script>
  <script>
    var vm = new Vue({
      el: '#divMsg',
      data: {
        empId: 1,
        empName: 'Mary'
      },
      methods: {
        showInfo: function () {
          return this.empId + "," + this.empName;
        }
      }
    });
    console.log( vm.$data );
    console.log( vm.$data.empName );
    console.log( vm.empName );
  </script>
</body>

</html>

 

Options參數物件包含一個名為「el」的屬性,被指派一個DOM元素的ID:「#divMsg」,「#」號代表ID選取器,而DIV標籤的ID為「divMsg」。接著在程式中定義一個「data」屬性,值是一個物件,包含「empId」、「empName」屬性。標籤中{{ empId }}將會被替代成「empId」的值「1」;而{{ empName }} 將會被替代成「empName」的值「Mary」。最後「data」物件,還包含一個「showInfo」函式,回傳「empId」、「empName」屬性值串接的字串;標籤中{{ showInfo() }}將會被替代成「showInfo」函式執行的回傳值。這個範例執行結果請參考下圖:

clip_image010

圖 5:範例執行結果。

範例結尾的三行JavaScript程式碼,利用console輸出除錯資訊到瀏覽器主控台。如果在Chrome瀏覽器執行上個範例的網頁,按下「F12」鍵開啟除錯工具(再按一次「F12」鍵可以關閉除錯工具),從除錯工具的主控台(Console)可以看到輸出以下內容:

clip_image012

圖 6:使用瀏覽器除錯主控台。

我們可以在程式碼中利用「vm.$data」取得Options物件的「data」屬性,此即為MVVM中的模型(Model)。而data物件的屬性會被轉換成getter/setter,例如「empId」屬性將被轉換成「get_empId(getter)」與「set_empId(setter)」函式。

 

雙向資料繫結

Vue.js專注在MVVM(Model - View - ViewModel)設計模式中的ViewModel層,透過雙向資料繫結語法,將檢視(View)與模型(Model)連結在一起。

  • 模型(Model):Model是一個JavaScript物件,提供資料。
  • 檢視(View):View是指由Vue實體負責管理的真正的DOM物件。
  • 檢視模型(ViewModel):在Vue.js中,每一個Vue實體就是一個ViewModel,此物件同步View與Model。

使用Vue.js,不太需要直接操作DOM,當資料異動時,將會自動更新View。Vue.js使用宣告式(declarative)語法,透過「v-model」指示詞(directive),來達成雙向資料繫結,讓你很容易搜集使用者輸入資料,以及異動資料。參考以下範例程式碼:

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title> Document </title>
</head>

<body>
  <div id="divMsg">
    <div> Employee Id :
      <input type="text" v-model="empId">
    </div>
    <br />
    <div> Employee Name :
      <input type="text" v-model="empName">
    </div>
    <div> Employee Info : {{ showInfo() }} </div>

  </div>
  <script src="js/vue.min.js"></script>
  <script>
    var o = {
      empId: 1,
      empName: 'Mary'
    };
    var vm = new Vue({
      el: '#divMsg',
      data: o,
      methods: {
        showInfo: function () {
          return this.empId + "," + this.empName;
        }
      }
    });
  </script>
</body>

</html>

這個範例程式的執行結果參考如下,當你在文字方塊中修改員工的資料時,異動的資料也會馬上顯示在下方區塊:

clip_image014

圖 7:範例執行結果。

使用元件(Component)

元件(Component)是可以被重複使用的Vue實體,因為元件是Vue實體,因此建立元件時,可以傳入Options參數物件,來設定data、methods等。

通常元件可以包含以下項目:

  • HTML標籤:用來設定元件的結構。
  • CSS樣式:用來設定元件的外觀,像字型、顏色、框線等等。
  • JavaScript程式碼:設定元件的資料,以及元件的行為。

元件(Component)可以包含以下屬性:

  • 「template」:指定元件要顯示的外觀,通常包含HTML標籤。
  • 「props」:可以指定為字串陣列,或物件,用來從父元件傳送資料。
  • 「data」:必需指定為一個回傳物件的函式,而不是一個純物件。如此可以讓元件的每一個實體都擁有自己的資料。
  • 「events」:用來接聽事件。
  • 「methods」:指定為函式,定義元件可以執行的行為。
  • 「computed」:計算屬性,在相依項目變動時,能自動重新計算值,並更新到DOM。

在前文的範例中,我們已經看到了建立元件的第一種方式:

var vm = new Vue({
  el: '#divMsg',
  data: o,
  methods: {
    showInfo: function () {
      return this.empId + "," + this.empName;
    }
  }
});

 

這種元件沒有對應的元件標籤,我們通常稱為主要容器元件(Main Container Component)。

 

使用Vue.component()函式建立元件

第二種建立元件的方式是採用「Vue.component()」函式,以此函式定義的元件可以允許你自訂元件標籤,並且能在網頁中重複的使用。以此函式建立的元件將會註冊在全域範圍(Global),直接可以在網頁程式之中使用。

以下是使用「Vue.component()」函式建立元件的範例程式:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title> Document </title>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>
    <script id="my-template" type="x-template">
            <div>
                    <label> {{promptText}} :</label>
                    <input type="text" v-model="myName" />
            </div>
    </script>
</head>

<body>
    <div id="app">
        <h2> {{title}} </h2>
        <my-component v-bind:my-Name="userName"> </my-component>
    </div>
    <script>
        Vue.component('my-component', {
            template: '#my-template',
            props: ['myName'],
            data: function () {
                return {
                    promptText: 'User Name'
                }
            }
        });

        var vm = new Vue({
            el: '#app',
            data: {
                userName: 'Mary',
                title: 'My App'
            }
        });
        console.dir( vm.$data.userName );
    </script>

</body>

</html>

 

我們利用<script id="my-template" type="x-template">區塊來定義元件的外觀,元件只能有一個根項目,因此範例中將元件的內容使用一個<div>標籤包起來:

<script id="my-template" type="x-template">
        <div>
                <label> {{promptText}} :</label>
                <input type="text" v-model="myName" />
        </div>
</script>

「Vue.component()」函式的第一個參數指定元件的名稱,元件的名稱可以採用兩種命名方式「kebab-case」或「PascalCase」。在此使用kebab-case命名法命名為「my-component」。元件接收一個「myName」props,用來傳送父元件資料(#app的userName)到子元件��my-component的myName)。

接著我們在程式中初始化根元件「#app」:

var vm = new Vue({
         el: '#app',
         data: {
             userName: 'Mary',
             title: 'My App'
         }
     });

 

在app中直接使用「my-component」標籤來插入元件:

<div id="app">
    <h2> {{title}} </h2>
    <my-component v-bind:my-Name="userName"> </my-component>
</div>

在HTML Attribute裏頭 「my-Name」大小寫視為相同,可以修改為:

<div id="app">
        <h2> {{title}} </h2>
        <my-component v-bind:my-name="userName"> </my-component>
    </div>

 

這個範例程式的執行結果請參考下圖所示:

clip_image016

圖 8:使用Vue.component()函式建立元件範例。

我們也可以直接將樣板定義在「template」屬性之中,修改上例程式碼如下:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title> Document </title>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"> </script>
</head>

<body>
    <div id="app">
        <h2> {{title}} </h2>
        <my-component v-bind:my-Name="userName"> </my-component>
    </div>
    <script>
        Vue.component('my-component', {
            template: '<div class="myclass"><label>{{promptText}} :</label><input type="text" v-model="myName"></div>',
            props: ['myName'],
            data: function () {
                return {
                    promptText: 'User Name'
                }
            }
        });
      
        var vm = new Vue({
            el: '#app',
            data: {
                userName: 'Mary',
                title :'My App'
            }
        });
        console.dir( vm.$data.userName );
    </script>

</body>

</html>

若要採用「PascalCase」命名元件名稱,請參考以下範例:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title> Document </title>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"> </script>
    <script id="my-template" type="x-template">
            <div>
                    <label> {{promptText}} :</label>
                    <input type="text" v-model="myName" />
            </div>
    </script>
</head>

<body>
    <div id="app">
        <h2> {{title}} </h2>
        <my-Component v-bind:my-name="userName"> </my-Component>
    </div>
    <script>
        Vue.component('MyComponent', {
            template: '#my-template',
            props: ['myName'],
            data: function () {
                return {
                    promptText: 'User Name'
                }
            }
        });

        var vm = new Vue({
            el: '#app',
            data: {
                userName: 'Mary',
                title: 'My App'
            }
        });
        console.dir( vm.$data.userName );
    </script>

</body>

</html>

建立區域元件(Local Component)

建立元件的第三種方式是使用區域元件(Local Component),它不是全域的,只能給特定的元件存取,因此很適合達到封裝(encapsulation)的效果。

參考以下範例程式碼,只要將一個有定義元件該有的屬性(template、props...等等)之物件指派給一個變數(myComponent),然後在「#app」元件中,便可以使用「components」屬性來使用「my-component」區域元件:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title> Document </title>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"> </script>
    <script id="my-template" type="x-template">
        <div>
                <label> {{promptText}} :</label>
                <input type="text" v-model="myName" />
        </div>
</script>

</head>

<body>
    <div id="app">
        <h2> {{title}} </h2>
        <my-component v-bind:my-Name="userName"> </my-component>
    </div>
    <script>
        var myComponent = {
            template: '#my-template',
            props: ['myName'],
            data: function () {
                return {
                    promptText: 'User Name'
                }
            }
        };
      
        var vm = new Vue({
            el: '#app',
            data: {
                userName: 'Mary',
                title :'My App'
            },
            components: {
                'my-component': myComponent
            }
        });
        console.dir( vm.$data.userName );
    </script>

</body>

</html>

範例中Vue實體(#app)包含一個私有元件(Private Component):「my-component」,我們更改使用「kebab-case」命名法,以便在Vue實體中的HTML標籤內使用:

var vm = new Vue({
          el: '#app',
          data: {
              userName: 'Mary',
              title :'My App'
          },
          components: {
              'my-component': myComponent
          }
      });

 

另外在我們在程式中定義了一個「myComponent」元件,「template」指定為「#my-template」:

var myComponent = {
            template: '#my-template',
            props: ['myName'],
            data: function () {
                return {
                    promptText: 'User Name'
                }
            }
        };

 

「props」屬性是一個陣列,包含元件擁有的特性(attribute):「myName」。在元件中,「data」屬性必需是一個函式,用來回傳資料。在範例中,回傳一個物件,包含「promptText」屬性,以在元件樣板中{{promptText}}所在位置顯示提示字串「User Name」。

比較特別的是,範例中元件「props」擁有的「myName」使用camel Cased命名法,而在DOM樣板中,大小寫視為相同,因此在宣告式的標籤中,建議使用kebab-case命名法「my-Name」:

<my-component v-bind:my-Name="userName"> </my-component>

此範例的執行結果如圖 8所示。

目前評分 5.0 , 共有 2 人參與

  • Currently 5.0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags:

.NET Magazine國際中文電子雜誌 | JavaScript | 許薰尹Vivid Hsu

NET Magazine國際中文電子雜誌

NET Magazine國際中文電子版雜誌,由恆逸資訊創立於2000,自發刊日起迄今已發行超過500篇.NET相關技術文章,擁有超過40000名註冊讀者群。NET Magazine國際中文電子版雜誌希望藉於電子雜誌與NET Developer達到共同學習與技術新知分享,歡迎每一位對.NET 技術有興趣的朋友們多多支持本雜誌,讓作者群們可以有持續性的動力繼續爬文。<請加入免費訂閱>

月分類Month List