【vue大師晉級之路第一集:Vue基礎】第2章——Vue 例項
阿新 • • 發佈:2018-11-03
建立一個 Vue 例項
每個 Vue 應用都是通過用 Vue 函式建立一個新的 Vue 例項開始的:
var vm = new Vue({
// 選項
})
Vue 應用由一個通過 new Vue 建立的根 Vue 例項,以及可選的巢狀的、可複用的元件樹組成。舉個例子,一個 todo 應用的元件樹可以是這樣的:
根例項 └─ TodoList ├─ TodoItem │ ├─ DeleteTodoButton │ └─ EditTodoButton └─ TodoListFooter ├─ ClearTodosButton └─ TodoListStatistics
資料與方法
當一個 Vue 例項被建立時,它向 Vue 的響應式系統中加入了其 data 物件中能找到的所有的屬性。當這些屬性的值發生改變時,檢視將會產生“響應”,即匹配更新為新的值。
// 我們的資料物件 var data = { a: 1 } // 該物件被加入到一個 Vue 例項中 var vm = new Vue({ data: data }) // 獲得這個例項上的屬性 // 返回源資料中對應的欄位 vm.a == data.a // => true // 設定屬性也會影響到原始資料 vm.a = 2 data.a // => 2 // ……反之亦然 data.a = 3 vm.a // => 3
當這些資料改變時,檢視會進行重渲染。值得注意的是只有當例項被建立時 data 中存在的屬性才是響應式的。也就是說如果你新增一個新的屬性,比如:
vm.b = 'hi'
那麼對 b 的改動將不會觸發任何檢視的更新。如果你知道你會在晚些時候需要一個屬性,但是一開始它為空或不存在,那麼你僅需要設定一些初始值。比如:
data: {
newTodoText: '',
visitCount: 0,
hideCompletedTodos: false,
todos: [],
error: null
}
這裡唯一的例外是使用 Object.freeze(),這會阻止修改現有的屬性,也意味著響應系統無法再追蹤變化。
<div id="app">
<p>{{ foo }}</p>
<!-- 這裡的 `foo` 不會更新! -->
<button v-on:click="foo = 'baz'">Change it</button>
</div>
var obj = {
foo: 'bar'
}
Object.freeze(obj)
new Vue({
el: '#app',
data: obj
})
除了資料屬性,Vue 例項還暴露了一些有用的例項屬性與方法。它們都有字首 $,以便與使用者定義的屬性區分開來。例如:
var data = { a: 1 }
var vm = new Vue({
el: '#example',
data: data
})
vm.$data === data // => true
vm.$el === document.getElementById('example') // => true
// $watch 是一個例項方法
vm.$watch('a', function (newValue, oldValue) {
// 這個回撥將在 `vm.a` 改變後呼叫
})
例項生命週期鉤子
每個 Vue 例項在被建立時都要經過一系列的初始化過程——例如,需要設定資料監聽、編譯模板、將例項掛載到 DOM 並在資料變化時更新 DOM 等。同時在這個過程中也會執行一些叫做生命週期鉤子的函式,這給了使用者在不同階段新增自己的程式碼的機會。
比如 created 鉤子可以用來在一個例項被建立之後執行程式碼:
new Vue({
data: {
a: 1
},
created: function () {
// `this` 指向 vm 例項
console.log('a is: ' + this.a)
}
})
// => "a is: 1"
也有一些其它的鉤子,在例項生命週期的不同階段被呼叫,如 mounted、updated 和 destroyed。生命週期鉤子的 this 上下文指向呼叫它的 Vue 例項。
不要在選項屬性或回撥上使用箭頭函式,
比如 created: () => console.log(this.a) 或 vm.$watch('a', newValue => this.myMethod())。
因為箭頭函式是和父級上下文繫結在一起的,this 不會是如你所預期的 Vue 例項,
經常導致 Uncaught TypeError: Cannot read property of undefined
或 Uncaught TypeError: this.myMethod is not a function 之類的錯誤。