前言
在前面篇幅 Vue的響應式原理中知道,當在Vue執行個體中聲明Prop時,會通過 Object.defineProperty 進行對象的重寫,同時增加屬性監聽,來觸發事件通知,在此基礎上,這節看下在Vue執行個體中怎麼使用這些資料。
初使用
var data = { id: "0001" }
var vm = new Vue({ data: data });
console.log("比較屬性值是否相同:" + (vm.id == data.id));
data.id = "0002";
console.log("修改data的資料後,vm.id is " + vm.id);
vm.id = "0003";
console.log("修改vm.id的資料後,data.id " + data.id);
當在初始化Vue執行個體時,進行 data的初始化,data屬性是Vue的配置項,初始化階段,Vue會對這個對象進行響應式配置,這些數值變更時,視圖即會重新進行渲染。
值得注意的是:隻有在Vue執行個體被建立時就已存在于 data 中的 property 才是響應式的,即動态新添加的 property 不會觸發視圖的變更 ,如下面的内容
vm.text = "新增的屬性" // 不屬于響應式屬性
是以,如果可以提前知道需要哪些property, 就可以提前建立, 初始化為空或是設定初始值。如
var vm = new Vue({
data: {
count: 0,
todoList: [],
text: ""
}
})
Vue 除了資料 property,還提供了執行個體 property ,以字首 $ 進行暴露
var data = { id: "0001" }
var vm = new Vue({ data: data, el: '#app', render: h => h(App), store });
console.log("執行個體 property $data 與 參數 data是否相等: " + (vm.$data === data));
console.log("綁定的dom元素是否相同:" + (vm.$el === document.getElementById("app")))
暴露的執行個體property清單
執行個體property | 說明 |
$data | Vue 執行個體觀察的資料對象。Vue 執行個體代理了對其 data 對象 property 的通路 |
$props | 目前元件接收到的 props 對象。Vue 執行個體代理了對其 props 對象 property 的通路 |
$el | Vue 執行個體使用的根 DOM 元素 |
$options | 用于目前 Vue 執行個體的初始化選項。需要在選項中包含自定義 property 時會有用處 |
$parent | 父執行個體,如果目前執行個體有的話 |
$root | 目前元件樹的根 Vue 執行個體。如果目前執行個體沒有父執行個體,此執行個體将會是其自己 |
$children | 目前執行個體的直接子元件。需要注意 $children 并不保證順序,也不是響應式的 |
$slots | 用來通路被插槽分發的内容 |
$refs | 一個對象,持有注冊過ref attribute 的所有 DOM 元素群組件執行個體 |
$attrs | 包含了父作用域中不作為 prop 被識别 (且擷取) 的 attribute 綁定 (class 和 style 除外) |
$listeners | 包含了父作用域中的 (不含 .native 修飾器的) v-on 事件監聽器 |
總結
在Vue執行個體中,可以通過響應式的方式進行資料綁定,也可以通過 Vue暴露的執行個體property 進行資料操作。以上有一個注意點,如果一個對象被 Object.freeze() 修飾,那這個對象也不會被響應式系統追蹤,如
var freeObject = {
id : "ttext"
}
// 會變成隻讀
Object.freeze(freeObject);
var vm = new Vue({ data: freeObject, el: '#app', render: h => h(App), store });
<div id="app">
<img alt="Vue logo" src="./assets/logo.png" />
<HelloWorld msg="Welcome to Your Vue.js App" />
<input v-model="name" />
<button @click="changeValue">change value</button>
<span>{{ this.$parent.id }}</span>
</div>