Vue.js

Vue js前端框架介紹與實作

張鈞名 2019/06/28 11:56:11
7248

基礎

瀏覽器相容性:

Vue 不支持 IE8 及以下版本,因為 Vue 使用了 IE8 無法模擬的 ES 5 特性。但它支持所有相容 ES 5 的瀏覽器。

 

使用

我們可以直接使用<script>標籤直接引入Vue.js。

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

 

聲明式渲染(Render)

Vue.js 的核心使用簡單的模板語法來將數據渲染進網頁的DOM系統中。

<div id="app">
  {{ message }}
</div>
var app = new Vue({ 
    el: '#app',
    data: {
        message: 'Hello Vue JS!'
    },
    
})

現在數據和 DOM 已經被建立了關聯,所有東西都是響應式的。我們要怎麼確認呢?打開你的瀏覽器的 JavaScript 控制台,我們可以找到app.message這個物件,我們修改它的值,網頁就會馬上更新文字。

 

我們也可以用這樣的方式來綁定值

<div id="app-2">
  <span v-bind:title="message">
    將滑鼠游標懸停幾秒鐘查看此處動態綁定的提示信息!
  </span>
</div>
var app2 = new Vue({
  el: '#app-2',
  data: {
    message: '頁面載入時間: ' + new Date().toLocaleString()
  }
})

 

如果想要控制一個元素的顯示也很簡單!

<div id="app-3">
  <p v-if="seen">你現在看到我了</p>
</div>
var app3 = new Vue({
  el: '#app-3',
  data: {
    seen: true
  }
})

Vue js 還有其他強大的指令,v-for 這個指令可以綁定陣列資料,來渲染出一個Html列表。

<div id="app-4">
  <ol>
    <li v-for="todo in todos">
      {{ todo.text }}
    </li>
  </ol>
</div>
var app4 = new Vue({
  el: '#app-4',
  data: {
    todos: [
      { text: '學習 JavaScript' },
      { text: '學習 Vue' },
      { text: '實作整個專案' }
    ]
  }
})

Vue js的事件處理也很簡單,我可以使用v-on指令來新增一個事件監聽器。

<div id="app-5">
  <p>{{ message }}</p>
  <button v-on:click="reverseMessage">反轉訊息</button>
</div>
var app5 = new Vue({
  el: '#app-5',
  data: {
    message: 'Hello Vue.js!'
  },
  methods: {
    reverseMessage: function () {
      this.message = this.message.split('').reverse().join('')
    }
  }
})

Vue js還提供了v-model指令,可輕鬆的實現前端表單輸入與js邏輯層狀態的雙向綁定。

<div id="app-6">
  <p>{{ message }}</p>
  <input v-model="message">
</div>
var app6 = new Vue({
  el: '#app-6',
  data: {
    message: 'Hello Vue!'
  }
})

 

組件化應用的建置:

組件系統在Vue js中是一個重要的概念,可以讓我們使用小型且獨立,可複用的組件來建構一個大型應用。

 

在Vue中註冊一個組件很簡單:

// 定義名稱為todo-item的新組件
Vue.component('todo-item', {
  template: '<li>這是一個代辦事項</li>'
})

 

現在我們可以用它來建構一個組件模板:

<div id="app">
  <ol>
    <todo-item></todo-item>
    <todo-item></todo-item>
  </ol>
</div>

這樣就可以達到複用的效果

接下來,我們來讓這個組件更複雜一點,我們來建構一個可以由父階層傳遞資料給子組件的方法,讓這個組件可以顯示不同的資訊。

Vue.component('todo-item', {
  // todo-item 組件現在接受一個"prop",類似一個自定義的屬性,而這個prop名稱為"todo"。
  props: ['todo'],
  template: '<li>{{ todo.text }}</li>'
})

我們可以使用v-bind指令將資料集for循環到每個項目中。

<ol>
   <!--
     現在我們為每個 todo-item 提供 todo 對象
     todo 對像是一個變數。我們也需要為每個組件提 
     供一個“key”,以便資料的處理。-->
   <todo-item
    v-for="item in foodList"
    v-bind:todo="item"
    v-bind:key="item.id">
   </todo-item>
</ol>
Vue.component('todo-item', {
  // todo-item 組件現在接受一個"prop",類似一個自定義的屬性,而這個prop名稱為"todo"。
  props: ['todo'],
  template: '<li>{{ todo.text }}</li>'
})

var app = new Vue({
  el: '#app',
  data: {
      foodList: [
          { id: 0, text: '蔬菜' },
          { id: 1, text: '起司' },
          { id: 2, text: '馬鈴薯' }
        ]
      }
})

 

Vue Instance(實例)

Vue Instance,官網翻譯為實例,可以解釋為實體化一個Vue的物件。

一個Vue的應用可以透過new vue來建立root Vue instance。

 

Data and Methods

當一個Vue實例被創建時,它會將data所有屬性加入到Vue的reactivity system(響應式系統),

也就是說當這些屬性值改變時,View會立即更新渲染為新的屬性值。

// 我們的數據對象
var data = { a: 1 }

// 該對象被加到一個Vue物件中
var vm = new Vue({
  data: data
})


// 數據對象屬性值與Vue物件屬性值是相同的
console.log(vm.a == data.a) // => true
 

// 設置Vue物件的屬性值,也會影響原有的數據屬性值
vm.a = 2
console.log(data.a) // => 2


// 反之亦然
data.a = 3
console.log(vm.a)  // => 3

除了數據屬性,Vue還提供了一些有用的實例屬性與方法,他們都有前缀字$,以分辨我們自訂的屬性或是官方提供的屬性方法。

例如:

var data = { a: 1 }
var vm = new Vue({
  el: '#app',
  data: data
})

// vm.$data跟data物件是相同的
console.log(vm.$data === data); // => true

// vm的$el方法跟js的document.getElementById找元素的方法是一樣的
console.log(vm.$el === document.getElementById('app'));  // => true


// $watch 是一個實例方法
vm.$watch('a', function (newValue, oldValue) {
    // 這個callback將在`vm.a` 改變後調用
    console.log(`newValue is ${newValue}`);
    console.log(`oldValue is ${oldValue}`);
})

// 改變data屬性a的值,就會觸發官方自訂的事件$watch
vm.$data.a = 2;

 

模板語法

Vue js使用基於Html的模板語法,允許開發者將DOM綁定至底層Vue實例中的數據。

Vue會將模板編譯成虛擬DOM渲染函數,並結合響應式系統,能計算出最少需要重新渲染那些組件,並把DOM的操作減少到最少。

 

插值

#文本

數據綁定最常見的方式就是使用"Mustache"語法,也就是跟Angular一樣使用兩個雙大括號:

<span>Message: {{ msg }}</span>

 

#原始Html

雙大括號會被解析為普通文本,如果想要輸出真正的Html,你需要使用v-html指令:

var vm = new Vue({
  el: '#app',
  data: {
    rawHtml: ' <span style="color: red">This should be red.</span>'
  }
})
<div id="app">
  <p>Using mustaches: {{ rawHtml }}</p>
  <p>Using v-html directive: <span v-html="rawHtml"></span></p>
</div>

 

#特性

Mustache語法不能作用在Html特性上,這時候您必須使用v-bind指令:

<div v-bind:id="dynamicId"></div>
<button v-bind:disabled="isButtonDisabled">Button</button>
var vm = new Vue({
  el: '#app',
  data: {
    // 動態id,隨機產生一個亂數  
    dynamicId: Math.random(),
    // 按鈕是否要禁用  
    isButtonDisabled: true
  }
})

 

#使用 JavaScript表達式

<div id="app">
  <!--數字相加-->
  <div>{{ number + 1 }}</div>
  <!--三元運算式-->
  <div>{{ ok ? 'YES' : 'NO' }}</div>
  <!--文字反轉-->
  <div>{{ message.split('').reverse().join('') }}</div>
  <!--動態綁定id-->
  <div v-bind:id="'list-' + id">動態綁定id</div>
</div>
var vm = new Vue({
  el: '#app',
  data: {
    // 數字  
    number: 1,
    // 布林值
    ok: true,
    // 文字  
    message: 'abcd',
    // id值  
    id: '123'  
  }
})

 

#參數

一些指令語法能接受一個參數,以指令名稱後面接冒號表示,如v-bind指令可以用於即時的更新html特性:

<a v-bind:href="url">昕力大學網站連結</a><br />

另一個例子是v-on指令,它用於監聽DOM事件:

<a v-on:click="doSomething">點擊事件</a>
var vm = new Vue({
  el: '#app',
  data: {
   url: 'https://www.tpisoftware.com/tpu/',
   doSomething: function() {
       alert('點擊了!');
   }      
  }
})

 

#動態參數

這是在2.6.0版本新增的,可以用方括號括起來代表JavaScript的一個表達式的指令參數:

<a v-bind:[attributeName]="url"> 昕力大學網站連結</a>

這邊要注意的是,可能是因為官網提到的attributeName為Vue的保留字,使用這個名稱會找不到定義。

用其他名稱即可:

var vm = new Vue({
  el: '#app',
  data: {
      bindhref: 'href',
      url: 'https://www.tpisoftware.com/tpu/',
      
  }
})
<a v-bind:[bindhref]="url"> 昕力大學網站連結</a>

 

計算屬性與監聽器

#計算屬性

如果有複雜的邏輯,都應該使用計算屬性。

使用說明如下:

<div id="example">
  <p>Original message: "{{ message }}"</p>
  <p>Computed reversed message: "{{ reversedMessage }}"</p>
</div>
var vm = new Vue({
  el: '#example',
  data: {
    message: 'Hello'
  },
  computed: {
    // 計算屬性的 getter
    reversedMessage: function () {
      // 'this' 指向vm實例物件
      return this.message.split('').reverse().join('')
    }
  }
})

計算屬性好處是他有快取的效用,這意思就是只要message還沒發生改變,多次呼叫reversedMessage計算屬性也會立即回應之前計算的結果,而不會再次執行函式。

 

#計算屬性VS監聽屬性

Vue提供了一種更通用的方式來觀察與響應Vue實例物件上數據的變動,也就是監聽屬性watch,但有些數據需要隨著其他數據變動而變動時,就很容易濫用了。

我們來看以下的例子:

<div id="demo">{{ fullName }}</div>
var vm = new Vue({
  el: '#demo',
  data: {
    firstName: 'Foo',
    lastName: 'Bar',
    fullName: 'Foo Bar'
  },
  watch: {
    firstName: function (val) {
      this.fullName = val + ' ' + this.lastName
    },
    lastName: function (val) {
      this.fullName = this.firstName + ' ' + val
    }
  }
})

再來比較計算屬性的寫法:

var vm = new Vue({
  el: '#demo',
  data: {
    firstName: 'Foo',
    lastName: 'Bar'
  },
  computed: {
    fullName: function () {
      return this.firstName + ' ' + this.lastName
    }
  }
})

是不是計算屬性比較簡潔呢?

只要firstName或lastName其中有個數據變動,就會呼叫計算屬性重新得到新的fullName,並刷新渲染畫面。

 

Class與Style綁定

要控制Html元素的Class,我可以用v-bind指令來處理。

 

#綁定Html Class

我們可以傳給v-bind:class一個物件對象,可以動態的切換class。

<div v-bind:class="{ active: isActive }"></div>

數據屬性isActive來決定這個active Class是否要顯示。

我們也可以傳入多組的Class來做切換,如下:

<div
  class="static"
  v-bind:class="{ active: isActive, 'text-danger': hasError }">
</div>
data: {
  isActive: true,
  hasError: true
}

Class渲染結果為:

<div class="static active text-danger"></div>

 

#陣列式語法

我們可以將一組陣列資料傳給v-bind:class

<div v-bind:class="[activeClass, errorClass]"></div>
data: {
  activeClass: 'active',
  errorClass: 'text-danger'
}

渲染為:

<div class="active text-danger"></div>

 

#綁定Html Style

v-bind:style語法非常直觀。

<div v-bind:style="{ color: activeColor, fontSize: fontSize + 'px' }"></div>
data: {
  activeColor: 'red',
  fontSize: 30
}

也可以直接綁定一個物件對象:

<div v-bind:style="styleObject"></div>
data: {
  styleObject: {
    color: 'red',
    fontSize: '30px'
  }
}

 

#陣列式語法

也可以綁定多個Style到同一個元素上:

<div v-bind:style="[baseStyles, overridingStyles]"></div>

 

條件渲染

v-if指令根據條件來顯示一個區塊內容。

<h1 v-if="awesome">Vue is awesome!</h1>

 

也可以用v-else指令顯示另一個區塊內容:

<h1 v-if="awesome">Vue is awesome!</h1>
<h1 v-else>Oh no!</h1>

 

另一種根據條件顯示區塊內容的指令是v-show

<h1 v-show="ok">Hello!</h1>

v-show指令還是會把Html DOM元素渲染出來,只是使用css屬性display來顯示隱藏。

 

v-if VS v-show

v-if是真實的條件渲染,它會確保顯示或隱藏時,真的去銷毀或重建其Html DOM元素與其綁定的事件。

v-show而不管是要顯示或隱藏都會真實的渲染出Html DOM元素,再用css屬性去隱藏或顯示。

 

列表渲染

我們前面有提到v-for指令來渲染一個列表。那我們來講解一些更深入的用法。

v-for區域中,我們可以訪問所有父作用區域的屬性。還支持當前項目的索引參數。

<ul id="example-2">
  <li v-for="(item, index) in items">
    {{ indexMessage }} - {{ index }} - {{ item.message }}
  </li>
</ul>
var example2 = new Vue({
  el: '#example-2',
  data: {
    indexMessage: 'Index',
    items: [
      { message: 'Foo' },
      { message: 'Bar' }
    ]
  }
})

我們也可以使用來遍歷一個物件的屬性。

<ul id="v-for-object" class="demo">
  <li v-for="value in object">
    {{ value }}
  </li>
</ul>
var example2 = new Vue({
  el: '#v-for-object',
  data: {
    object: {
      title: 'How to do lists in Vue',
      author: 'Jane Doe',
      publishedAt: '2016-04-10'
    }
  }
})

我們也可以使用第二個參數名稱(key name),與第三個參數名稱(index索引值):

<ul id="v-for-object" class="demo">
 <li v-for="(value, name, index) in object">
   {{ index }}. {{ name }}: {{ value }}
  </li>
</ul>

 

陣列更新檢測

#變異方法 (mutation method)

Vue有以下這些監聽陣列變動的變異方法,這些方法都會觸發視圖更新:

  • push()
  • pop()
  • shift()
  • unshift()
  • splice()
  • sort()
  • reverse()

所以我們可以在Vue實例中的陣列資料增加一組資料,列表就會再增加一筆資料。

example1.items.push({ message: 'Baz' })

 

事件處理

#監聽事件

可以用v-on指令來監聽DOM事件,並在觸發時運行一些js函式。

<div id="example-1">
 <button v-on:click="counter += 1">Add 1</button>
 <p>The button above has been clicked {{ counter }} times.</p>
</div>
var example1 = new Vue({
  el: '#example-1',
  data: {
    counter: 0
  }
})

我們點擊Add 1按鈕,Html中的點擊次數就會增加。

 

#事件呼叫方法

我們也可以將事件綁定我們寫好的方法。

<div id="example-2">
  <!-- `greet` 是方法名稱 -->
  <button v-on:click="greet">Greet</button>
</div>
var example2 = new Vue({
  el: '#example-2',
  data: {
    name: 'Vue.js'
  },
  // 在Vue實例中的`methods`屬性定義方法
  methods: {
    greet: function (event) {
      // `this`在方法中指的是當前的Vue實例
      alert('Hello ' + this.name + '!')
      // `event` 是原生DOM事件
      if (event) {
        alert(event.target.tagName)
      }
    }
  }
})

// 也可以直接呼叫方法,
// 直接呼叫方法,就不是來自於DOM事件觸發,
// 就沒有event,所以只會alert一次。
example2.greet(); // => 'Hello Vue.js!'

 

#事件修飾符

我們事件的方法中調用event.preventDefault()event.stopPropagation(),是很常見的用法。但是方法應該只有純粹的邏輯處理,而不是去處理DOM事件的一些細節。

所以Vue為v-on提供了事件修飾符。

  • .stop
  • .prevent
  • .capture
  • .self
  • .once
  • .passive
<!-- 阻止點擊事件繼續傳遞 -->
<a v-on:click.stop="doThis"></a>

<!-- 提交事件不再重載頁面 -->
<form v-on:submit.prevent="onSubmit"></form>

<!-- 修飾符可以串聯 -->
<a v-on:click.stop.prevent="doThat"></a>

<!-- 只有修飾符 -->
<form v-on:submit.prevent></form>

<!-- 添加事件監聽器時使用事件捕捉模式 -->
<!-- 即元素本身觸發的事件先在此處理,然後才交由內部元素處理 -->
<div v-on:click.capture="doThis">...</div>

<!-- 只當在event.target是當前元素本身時觸發處理函式 -->
<!-- 即事件不是從內部元素觸發的 -->
<div v-on:click.self="doThat">...</div>

<!-- 點擊事件只會觸發一次 -->
<a v-on:click.once="doThis"></a>
        
<!-- 滾動事件的默認行為 -->
<!-- 不會等待`onScroll`完成  -->
<!-- 這包含了`event.preventDefault()`的情況 -->
<div v-on:scroll.passive="onScroll">...</div>
        
<!-- 只有在 `key` 是 `Enter` 時調用`vm.submit()` -->
<input v-on:keyup.enter="submit">

 

#系統修飾鍵

可以用以下修飾符來實現按下對應的按鍵的監聽器。

  • .ctrl
  • .alt
  • .shift
  • .meta
<!-- Alt + C -->
<input @keyup.alt.67="clear">

<!-- Ctrl + Click -->
<div @click.ctrl="doSomething">Do something</div>
        
<!-- Alt 或 Shift同時按下觸發 -->
<button @click.ctrl="onClick">A</button>

<!-- 只有Ctrl按下才觸發 -->
<button @click.ctrl.exact="onCtrlClick">A</button>

<!-- 沒有任何系統修飾符按下才觸發 -->
<button @click.exact="onClick">A</button>

 

#鼠標按鈕修飾符

  • .left
  • .right
  • .middle

 

表單輸入綁定

可以用v-model指令在表單<input>、<textarea>、<select>元素上建立雙向數據綁定。

#文本

<div id="example-1">
  <input v-model="message" placeholder="edit me">
  <p>Message is: {{ message }}</p>
</div>   
var example1 = new Vue({
  el: '#example-1',
  data: {
    message: ''
  }
})

 

#多行文本

<div id="example-1">
  <span>Multiline message is:</span>
  <p style="white-space: pre-line;">{{ message }}</p>
  <br>
  <textarea v-model="message" placeholder="add multiple lines"> 
  </textarea>
</div>   

 

#複選框

單個複選框,綁定布林值:

<div id="example-1">
  <input type="checkbox" id="checkbox" v-model="checked">
  <label for="checkbox">{{ checked }}</label>
</div>   
var example1 = new Vue({
  el: '#example-1',
  data: {
    checked : false
  }
})

多個複選框,綁定同一個陣列:

<div id='example-3'>
  <input type="checkbox" id="jack" value="Jack" v-model="checkedNames">
  <label for="jack">Jack</label>
  <input type="checkbox" id="john" value="John" v-model="checkedNames">
  <label for="john">John</label>
  <input type="checkbox" id="mike" value="Mike" v-model="checkedNames">
  <label for="mike">Mike</label>
  <br>
  <span>Checked names: {{ checkedNames }}</span>
</div>
var example1 = new Vue({
  el: '#example-3',
  data: {
    checkedNames: []
  }
})

#Radio Button

<div id="example-4">
  <input type="radio" id="one" value="One" v-model="picked">
  <label for="one">One</label>
  <br>
  <input type="radio" id="two" value="Two" v-model="picked">
  <label for="two">Two</label>
  <br>
  <span>Picked: {{ picked }}</span>
</div>
var example1 = new Vue({
  el: '#example-4',
  data: {
    picked: ''
  }
})

 

#下拉選單

<div id="example-5">
  <select v-model="selected">
    <option disabled value="">請選擇</option>
    <option>A</option>
    <option>B</option>
    <option>C</option>
  </select>
  <span>Selected: {{ selected }}</span>
</div>
var example1 = new Vue({
  el: '#example-5',
  data: {
    selected: ''
  }
})

#下拉選單複選

<div id="example-6">
  <select v-model="selected" multiple style="width: 50px;">
    <option>A</option>
    <option>B</option>
    <option>C</option>
  </select>
  <br>
  <span>Selected: {{ selected }}</span>
</div>
var example1 = new Vue({
  el: '#example-6',
  data: {
    selected: []
  }
})

 

v-for渲染動態下拉選單:

<div id="example-6">
  <select v-model="selected">
  <option v-for="option in options" v-bind:value="option.value">
    {{ option.text }}
  </option>
  </select>
  <span>Selected: {{ selected }}</span>
</div>
var example1 = new Vue({
  el: '#example-6',
  data: {
    // 預設選參數'C'選項  
    selected: 'C',
    options: [
      { text: 'One', value: 'A' },
      { text: 'Two', value: 'B' },
      { text: 'Three', value: 'C' }
    ]
  }
})

 

#值綁定

我們也可以使用v-model綁定到我們實例物件中的屬性值。

<div id="example-6">
  <!-- 當選中時,`picked`值為 "a" -->
  <input type="radio" v-model="picked" value="a">
  <br>
  <span>picked Selected: {{ picked }}</span>
  <!-- 當選中時,`toggle`值為true 或 false -->
  <br>
  <input type="checkbox" v-model="toggle">
  <span>toggle Selected: {{ toggle }}</span>
  <br>
  <!-- 當選中時,`selected`值為 "abc" -->
  <select v-model="selected">
    <option value="abc">ABC</option>
  </select>
  <br>
  <span>select Selected: {{ selected }}</span>
</div>
<!-- 也可以使用"true-value" 或 "false-value,來定義選中的值跟沒選中的值。" -->
<input
  type="checkbox"
  v-model="toggle"
  true-value="yes"
  false-value="no"
>

 

我們也可以使用v-bind來綁定一個動態物件屬性。

<select v-model="selected">
  <option v-bind:value="{ number: 123 }">123</option>
</select>
// 當選中時
typeof vm.selected // => 'object'
vm.selected.number // => 123

 

#修飾符

.lazy

<!-- 在"change"時才更新 -->
<input v-model.lazy="msg" >

.number

<!-- 限定輸入為數字型態時使用 -->
<input v-model.number="age" type="number">

.trim

<!-- 自動過濾輸入的字頭字尾空白 -->
<input v-model.trim="msg">

 

組件基礎

我們來定義一個名為"button-counter"的組件:

Vue.component('button-counter', {
  // 這邊要注意的是,組件的data為一個函式,函式要返回其對象物件屬性。
  data: function () {
    return {
      count: 0
    }
  },
  template: '<button v-on:click="count++">You clicked me {{ count }} times.</button>'
})

var example1 = new Vue({ el: '#components-demo' })

 

我們建立好組件後,就可以當作自定義元素來使用。

<div id="components-demo">
  <button-counter></button-counter>
</div>

組件好處就是可以複用:

<div id="components-demo">
  <button-counter></button-counter>
  <button-counter></button-counter>
  <button-counter></button-counter>
</div>

 

透過Prop向子組件傳遞數據:

Vue.component('button-counter', {
    // 定義兩個Prop屬性
    props: {
      // 字串屬性
      title: String,
      // 數字型態屬性
      increment: Number
    }

我們根據上一個例子,來做一些名稱的傳入與顯示,與設定按鈕每次遞增的數量:

Vue.component('button-counter', {
    // 定義兩個Prop屬性
    props: {
      // 字串屬性    
      title: String,
      // 數字型態屬性    
      increment: Number
    },
    data: function () {
        return {
          count: 0
        }
      },
  // 每次點擊,就增加傳入increment的遞增量    
  template: '<button v-on:click="count = count + increment">{{ title }} clicked me {{ count }} times.</button>'
})

var example1 = new Vue({ el: '#components-demo' })
<div id="components-demo">
  <button-counter v-bind:increment="1" title="Jimmy"></button-counter>
  <button-counter v-bind:increment="2" title="Joe"></button-counter>
  <button-counter v-bind:increment="3" title="John"></button-counter>
</div>

這邊要注意的是,increment是Number型態,要使用v-bind來傳遞動態物件屬性,不然接收到的會是字串。

 

監聽子組件事件

有時候在開發子組件的時候,會需要跟父階層組件溝通。

比如說,以上面的例子來說,我們想要知道是哪個人點擊了按鈕,並在父階層DOM元素顯示出名子。

<button-counter v-on:send-name="onSendName" v-bind:increment="1" title="Jimmy"></button-counter>

我們在子組件上定義一個子組件事件叫"send-name",並呼叫父階層方法"onSendName"。

template: `<button v-on:click="$emit('send-name', title)" v-on:click="count = count + increment">{{ title }} clicked me {{ count }} times.</button>`

並在子組件的template的按鈕增加點擊事件,透過$emit方法呼叫我們自定義的方法"send-name",並傳入"title"參數給方法。

var example1 = new Vue({ 
    el: '#components-demo',
    data: {
        clickMsg: 'No user click!'
    },
    methods: {
    onSendName: function (name) {
        this.clickMsg = `${name} click!`
    }
}
})

在父親階層定義方法"onSendName",並接受"name"參數,在那個方法中再處理其參數,再傳給我們自訂的實例物件屬性"clickMsg"。

<div id="components-demo">
  <button-counter v-on:send-name="onSendName" v-bind:increment="1" title="Jimmy"></button-counter>
  <button-counter v-on:send-name="onSendName" v-bind:increment="2" title="Joe"></button-counter>
  <button-counter v-on:send-name="onSendName" v-bind:increment="3" title="John"></button-counter>
  <div>{{ clickMsg }}</div>
</div>

父階層再將實例物件屬性"clickMsg"顯示出來。

所以我們點擊按鈕時,就可以把子組件屬性傳遞給父階層做處理。

 

結論

目前Vue js社群的成長度可以說相當快。

 

  Vue對於向上擴展或是向下擴展都有很好的相容性,在向上擴展方面,有提供強大的路由函式庫來對應大型應用專案,也有提供Vue-CLI來快速建構專案與打包專案。在向下擴展方面就類似於jQuery,只要把下面標籤放入頁面就能運行並可以進行開發了。

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

  在起步階段不需要額外學JSX、ES6、TypeScript,或是整個框架建構系統,只需要很短的時間就能建構出一個簡單的應用。

  在效能方面也可以說相當快,因為操作DOM的成本都是昂貴的,現今網頁的資料量都很龐大,其網頁的DOM元素也相對來得多,頻繁的更新會造成效能的瓶頸,而Vue使用Virtual DOM,Vue會精確知道哪個組件需要被渲染,所以在運行時的效能都是非常快的。

  Vue在Html跟css的整體思維還是擁抱經典的Web技術,在任何符合規範的Html都是合法的模板,這使得設計師與開發者都能更容易理解和參與其專案。

  想要學習Vue,只需要有良好的Html與JavaScript基礎就能進行開發,在現今JavaScript快速變化的世界中,真的可以說相當容易與快速上手。

張鈞名