本系列將介紹 Rails with Vue 的基本概念,並且以一個簡單的專案 Todo 來說明如何使用 Rails with Vue。我將透過這一系列的文章記錄我學習的過程,並且將我所學到的知識分享給大家。
- 【Day 01】淺入淺出 Rails with Vue - Before We Begin
- 【Day 02】淺入淺出 Rails with Vue - Vue 的基本概念 - 1
- 【Day 03】淺入淺出 Rails with Vue - Vue 的基本概念 - 2
- 【Day 04】淺入淺出 Rails with Vue - Vue 的基本概念 - 3
- 【Day 05】淺入淺出 Rails with Vue - Vue 的基本概念 - 4
- 【Day 06】淺入淺出 Rails with Vue - Vue 的基本概念 - 5
- 【Day 07】淺入淺出 Rails with Vue - Vue 的基本概念 - 6
Modifier
是用 .
表示的特殊後綴,它可以用來修飾 v-bind
或 v-on
指令,例如:
<form v-on:submit.prevent="onSubmit"> ... </form>
上面的例子中,我們使用了 .prevent
修飾符,它會呼叫 event.preventDefault()
,防止表單被送出。
在 Vue 中提供了一些簡寫的方式,用來簡化指令的撰寫,例如:
<!-- full syntax -->
<a v-bind:href="url"> ... </a>
<!-- shorthand -->
<a :href="url"> ... </a>
<!-- shorthand with dynamic argument (2.6.0+) -->
<a :[key]="url"> ... </a>
<!-- full syntax -->
<a v-on:click="doSomething"> ... </a>
<!-- shorthand -->
<a @click="doSomething"> ... </a>
<!-- shorthand with dynamic argument (2.6.0+) -->
<a @[event]="doSomething"> ... </a>
以上的 :
和 @
都是 valid 的,當我們使用 :
時,我們可以使用 v-bind
的所有修飾符,而 @
則是 v-on
的所有修飾符。
In-template expressions 是非常方便的,但是他們比較適合用在簡單的運算,當越來越多的邏輯被加入到模板中時,將會讓模板更難以維護,例如以下的例子:
<div id="example">
{{ message.split('').reverse().join('') }}
</div>
我們將 message
透過 split()
、reverse()
、join()
這三個函式來進行運算,這樣的寫法雖然可以達到我們的目的,但是這樣的寫法並不直覺,必須花一些時間理解,對於太多的邏輯運算我們可以使用 computed properties
來解決這個問題。
讓我們先從一個簡單的例子開始,我們將 message
透過 computed properties
來進行運算,以下是範例:
<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: {
// a computed getter
reversedMessage: function () {
// `this` points to the vm instance
return this.message.split('').reverse().join('')
}
}
})
在上面的範例中,我們定義了一個 computed properties
,它的名稱是 reversedMessage
,我們可以透過 vm.reversedMessage
來取得它的值,而它的值是透過 message
來進行運算的,這樣的寫法比較直覺,也比較好維護。
你可以打開瀏覽器的 console 來觀察 vm.reversedMessage
的值,當你修改 vm.message
的值時,vm.reversedMessage
的值也會跟著改變。
console.log(vm.reversedMessage) // => 'olleH'
vm.message = 'Goodbye'
console.log(vm.reversedMessage) // => 'eybdooG'
在先前的範例中,我們使用了 computed properties
,但是你也可以使用 methods
來達到相同的效果,例如:
<p>Reversed message: "{{ reverseMessage() }}"</p>
// in component
var vm = new Vue({
el: '#example',
data: {
message: 'Hello'
},
methods: {
reverseMessage: function () {
return this.message.split('').reverse().join('')
}
}
})
在上面的範例中,我們使用了 methods
來達到相同的效果,但是這樣的寫法並不直覺,因為我們需要在模板中加入 ()
,這樣的寫法也比較沒有效率,因為每次呼叫 reverseMessage()
時,都會重新執行函式,而 computed properties
則是會透過 caching
來達到效率的提升。
需特別注意的是,computed properties
是基於它們的依賴進行緩存的,只有在它們的相依值發生改變時才會重新計算。
computed: {
now: function () {
return Date.now()
}
}
在上面的範例中,now
這個 computed properties
會在每次呼叫時都會一樣,因為 Date.now()
不依賴於任何的值,所以它不會重新計算。
所以為什麼我們需要 Caching
?當我們有一個非常耗時的運算時,如果沒有 Caching
,那麼每次呼叫時都會重新計算,這樣會造成效能的問題,所以我們需要 Caching
來達到效率的提升。
Vue 提供了一個方法來監聽資料的變化,這個方法就是 watch
,我們可以透過 watch
來監聽資料的變化,當資料發生變化時,我們可以透過 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
}
}
})
在上面的範例中,我們使用了 watch
來監聽 firstName
與 lastName
的變化,當它們發生變化時,我們會透過 watch
來執行一些函式,這樣的寫法比較沒有效率,因為我們需要在 watch
中寫入兩個函式,而且這兩個函式的內容是一樣的,所以我們可以透過 computed properties
來達到相同的效果,例如:
var vm = new Vue({
el: '#demo',
data: {
firstName: 'Foo',
lastName: 'Bar'
},
computed: {
fullName: function () {
return this.firstName + ' ' + this.lastName
}
}
})
computed properties
也可以設定 setter,例如:
// ...
computed: {
fullName: {
// getter
get: function () {
return this.firstName + ' ' + this.lastName
},
// setter
set: function (newValue) {
var names = newValue.split(' ')
this.firstName = names[0]
this.lastName = names[names.length - 1]
}
}
}
// ...
在上面的範例中,我們設定了 fullName
的 setter,當我們呼叫 vm.fullName = 'John Doe'
時,setter 會被呼叫,並且會將 John Doe
分割成 firstName
與 lastName
。