在程式開發中,我們很常會使用 console.log
來了解目前程式碼的狀況或偵錯,而這次在研究 vue 的生命週期中,遇到了一些關於 console.log
的問題:
在寫 vue 時我們可以透過 data return 的物件作為資料,並做一些操作或者渲染到畫面中。而 beforeCreate、created 則代表著 vue 實例的生命週期,不同的生命週期中所要操作的任務都不同,如下方範例簡單來說,beforeCreate 依照理論來說是無法取到 data 中的 sum ,而當我們 console.log(this.sum);
得到 undefined 確實也不意外;可是當我 console.log(this);
並且打開物件內的內容時,我們可以看到 sum: 0
這樣的屬性與值,瞬間腦袋就斷片了。
// index.vue
<template>
<div id="app">
<h2>Lifecycle</h2>
<p>計數:{{ sum }}</p>
<button @click="sum += 1">按鈕</button>
</div>
</template>
<script>
export default {
data() {
return {
sum: 0,
};
},
beforeCreate() {
console.log(this);
/*
以下表點開 this 物件中,所包含的屬性
$attrs: (...)
$children: []
$createElement: ƒ (a, b, c, d)
$el: div#app
$listeners: (...)
$options: {parent: Vue, _parentVnode: VNode, propsData: undefined, _parentListeners: undefined, _renderChildren: undefined, …}
$parent: Vue {_uid: 0, _isVue: true, $options: {…}, _renderProxy: Proxy, _self: Vue, …}
$refs: {}
$root: Vue {_uid: 0, _isVue: true, $options: {…}, _renderProxy: Proxy, _self: Vue, …}
$scopedSlots: {$stable: true, $key: undefined, $hasNormal: false}
$slots: {}
$vnode: VNode {tag: 'vue-component-2', data: {…}, children: undefined, text: undefined, elm: div#app, …}
sum: 0
*/
console.log(this.sum); // undefined
},
created() {
console.log(this.sum); // 0
},
};
</script>
一開始遇到這樣的問題時,還在思考說會不會是 vue 的概念理解不對,一時間也不曉得到底要下什麼關鍵字搜尋這樣的問題,而在迷茫中先看到了 stack overflow 上的這篇文章、以及 MDN console.log,雖然英文不太好,但好像有一點了解狀況了,似乎是 console.log 物件時,這個物件不論是在哪邊被 log ,都會顯示最新的更動狀況,再回到上方的範例中,就能理解在 beforeCreate log 出來的 this ,已經不是在 beforeCreate 生命週期得到的 this 了。
詳細也能到 huli 大大寫的這篇文章,有完整講述這樣的狀況。
結論
這樣的問題因為一些關係所以是無法解決的,但我們可以了解這樣的狀況以及解決辦法:
- 不 log 整個物件,可以 log 我們需觀察的屬性值。
console.log(obj.xxx) // O console.log(obj) // x
- JSON.parse(JSON.stringify(obj)) 深拷貝
- debugger 下斷點,讓程式不往下執行
// ...前略 beforeCreate() { console.log(this); // 因為有了 debugger 所以 this 就會符合 beforeCreate 這個環境中正確的值。 debugger; }, // ...後略