創造Vue實體 (Creating a Vue Instance)

  • 所有的Vue app 都會從創造實例(Instance)開始
  • 裡面的options處就是我們操作的地方,可以瀏覽 API reference來做操作
1
2
3
var vm = new Vue({
// options
})
  • 一個Vue app通常會有會有個root Vue instance由new Vue產生
  • 伴隨著的是巢狀的樹組成的component,它具有可重複使用的特性
  • 在ROOT下面的都是component的部分
1
2
3
4
5
6
7
8
Root Instance
└─ TodoList
├─ TodoItem
│ ├─ TodoButtonDelete
│ └─ TodoButtonEdit
└─ TodoListFooter
├─ TodosButtonClear
└─ TodoListStatistics

範例

index.js

1
2
3
4
5
6
7
var app = new Vue({
el:#app,
data: {
product: "Socks"

})

index.html

1
2
3
4
<div id="app">
<h2>{{ product }} </h2>
</div>

  • app使用el連接到html檔案內部的id = “app”的div
  • 連結app內的data: poduct到html上
  • 藉由改變index.js 內 product的內容可以及時修改html內的的內容

呈現在網頁上的結果

藉著改變屬性也可以及時修改頁面內容

1
2
3
4
5
app.product = 'Coat'
//印出結果變成Coat

app.product = "Compass"
//印出結果變成Compass

資料與方法(Data and Methods)

$data

1
<div id="app">{{msg}}</div>
1
2
3
4
5
6
7
8
let data = {
msg: '123123'
}

let vm = new Vue({
el: '#app',
data,
});

這兩個是相同的結果

1
2
3
vm.$data === data   //true

data.msg === vm.msg //true

因此當我們操作

1
2
data.msg =456
vm.msg = 123

畫面也會如此響應

但是如果使用不存在的屬性時畫面則不會響,得使用不同的方法

1
vm.b = 'hi'

但是如果你知道可能稍後會有屬性會使用到,但目前得空著或是還未存在,因此就必須設預設值

比方說要規畫一個todoList app可能會使用到的data:

1
2
3
4
5
6
7
data: {
newTodoText: '',
visitCount: 0,
hideCompletedTodos: false,
todos: [],
error: null
}

Object.freeze()

可以關閉reative,讓畫面不被響應

1
<div id="app">{{msg}}</div>
1
2
3
4
5
6
7
8
9
10
let data = {
msg: 'hello Vue'
}

Object.freeze(data);

let vm = new Vue({
el: '#app',
data,
});

在這個情況下

1
2
data.msg =456
vm.msg = 123

畫面也不會有任何響應

並vm也會變成只能讀不能寫

$前綴API

$這個符號代表Vue提供給我們的功能

$data,
$el,
$watch等等

Instance Properties

生命週期裝置實例(Instance Lifecycle Hooks)

到特定的時間就會呼叫特定的函式

每個Vue實體都會經歷一連串的初始化階段舉例:

  1. 需要設置好data observation
  2. 編譯模板
  3. 把Vue實體推到DOM上
  4. 更新DOM當data被更新

在這個階段過程中也會跑一些functions被稱為Lifecycle Hooks,讓使用者寫自己的程式碼在特定的階段使用

範例

當Vue實體已經被創造時,created這個函式可以被使用:

1
2
3
4
5
6
7
8
9
10
new Vue({
data: {
a: 1
},
created: function () {
// `this` points to the vm instance
console.log('a is: ' + this.a)
}
})
// => "a is: 1"

在不同的階段還有其他的hooks會被呼叫例如:

所有的hook指向調用它的實體

  • mounted
  • updated
  • destroyed

作者提醒

千萬不要使用箭頭函式在Vue實體,因為箭頭函示沒有this常常會導致報錯

1
2
Uncaught TypeError: Cannot read property of undefined 
Uncaught TypeError: this.myMethod is not a function

使用一般的函式:

1
2
3
4
5
6
7
8
new Vue({
data: {
a: 1
},
created: function () {
console.log(this)
}
})

才能印出 Vu實體

使用箭頭函式:

1
2
3
4
5
6
7
8
new Vue({
data: {
a: 1
},
created: () => {
console.log(this)
}
})

只會印出外層的windows

Lifecycle Diagram

從上方那張圖可以得知hook如下:

beforeCreate
Vue實體初始化後立刻呼叫此函式,不過此時Vue實體還未創建所以其中的設定都還未能使用(如data observation, event, watcher setup)

created
Vue實例創建完成後立刻呼叫此函式,已設置 data, computed properties, methods, watch/event callbacks,但尚未開始mounting階段,且 $el 還不能在此階段使用。

beforeMount
在mounting階段開始前被調用:render function首次被調用。

mounted
選項物件中的el被新創建的vm.$el替換,並掛載到到 vm 上,並調用mounted這個鉤子。

beforeUpdate
數據被更新時會調用,發生在 Virtual DOM re-render 和 patch 之前(連結:Day4: Virtual DOM),可以在此時更改狀態數據,並不會增加重新渲染的成本。

updated
由於數據更新導致 Virtual DOM re-render 和 patch 之後會調用updated這個鉤子。

不精確白話文為:由於updated被調用時,DOM 已經更新。所以在此時更新數據很可能會導致updated無限循環的被調用。

beforeDestroy
在 Vue Instance 被銷毀前被調用,因此 Vue Instance 在beforeDestroy中仍可運作。

不精確白話文為:Vue Instance 可以在此時做垂死前的掙扎。

destroyed
在 Vue Instance 被銷毀後被調用,此時 Vue Instance 所有東西會解除綁定,事件監聽也都會被移除,子實例也會被銷毀。

模板語法(Template Syntax)