هوک های چرخه عمر (Lifecycle Hooks)
«هوک چرخه عمر (Lifecycle Hook)» یعنی جای خاصی در زندگی یک کامپوننت که می توانیم کد اجرا کنیم. مثل زنگ شروع کلاس یا زنگ تفریح در مدرسه؛ هر زنگ، کاری دارد.
beforeCreate: قبل از ساخت کامپوننت
در هوک beforeCreate هنوز داده ها و متدها آماده نیستند. پس به data یا DOM دست نزن.
<template>
<h2>Component</h2>
<p>This is the component</p>
<p id="pResult">{{ text }}</p>
</template>
<script>
export default {
data() {
return {
text: "..."
};
},
beforeCreate() {
this.text = "initial text";
console.log("beforeCreate: The component is not created yet.");
}
};
<\/script>
<template>
<h1>The 'beforeCreate' Lifecycle Hook</h1>
<p>We can see the console.log() message from 'beforeCreate' lifecycle hook, but there is no effect from the text change we try to do to the Vue data property, because the Vue data property is not created yet.</p>
<button @click="this.activeComp = !this.activeComp">Add/Remove Component</button>
<div>
<comp-one v-if="activeComp"></comp-one>
</div>
</template>
<script>
export default {
data() {
return {
activeComp: false
};
}
};
<\/script>
<style>
#app > div {
border: dashed black 1px;
border-radius: 10px;
padding: 10px;
margin-top: 10px;
background-color: lightgreen;
}
#pResult {
background-color: lightcoral;
display: inline-block;
}
<\/style>
created: داده ها آماده می شوند
در created داده ها و متدها حاضرند. اما هنوز درخت DOM سوار نشده است.
<template>
<h2>Component</h2>
<p>This is the component</p>
<p id="pResult">{{ text }}</p>
</template>
<script>
export default {
data() {
return {
text: "..."
};
},
created() {
this.text = "initial text";
console.log("created: The component just got created.");
}
};
<\/script>
beforeMount: هنوز به DOM وصل نشده
در beforeMount عنصرهای DOM در دسترس نیستند. پس با ref کاری نکن.
<template>
<h2>Component</h2>
<p>This is the component</p>
<p ref="pEl" id="pEl">We try to access this text from the 'beforeMount' hook.</p>
</template>
<script>
export default {
beforeMount() {
console.log("beforeMount: just before mount.");
this.$refs.pEl.innerHTML = "Hello World!";
}
};
<\/script>
mounted: بهترین زمان کار با DOM
در mounted کامپوننت داخل DOM است. اکنون می توانی با ref کار کنی.
<template>
<h2>Form Component</h2>
<p>When mounted, focus the input.</p>
<form @submit.prevent>
<label>
<p>Name:<br><input type="text" ref="inpName"></p>
</label>
<label>
<p>Age:<br><input type="number"></p>
</label>
<button>Submit</button>
</form>
</template>
<script>
export default {
mounted() {
this.$refs.inpName.focus();
}
};
<\/script>
beforeUpdate: قبل از رندرِ تغییرات
وقتی داده عوض می شود، قبل از رندر، beforeUpdate اجرا می شود. اینجا می توانی لاگ بنویسی.
<template>
<h1>The 'beforeUpdate' Lifecycle Hook</h1>
<p>Safe to modify logs here.</p>
<button @click="this.activeComp = !this.activeComp">Add/Remove Component</button>
<div>
<comp-one v-if="activeComp"></comp-one>
</div>
<ol ref="divLog"></ol>
</template>
<script>
export default {
data() {
return {
activeComp: true
};
},
beforeUpdate() {
this.$refs.divLog.innerHTML += "<li>beforeUpdate ran.</li>";
}
};
<\/script>
<style>
#app > div {
border: dashed black 1px;
border-radius: 10px;
padding: 10px;
margin-top: 10px;
background-color: lightgreen;
}
<\/style>
updated: بعد از رندرِ تغییرات
در updated صفحه دوباره رندر شده است. بنابراین محتاط باش و DOM را عوض نکن.
<template>
<h1>The 'updated' Lifecycle Hook</h1>
<p>Updating causes console.log here.</p>
<button @click="this.activeComp = !this.activeComp">Add/Remove Component</button>
<div>
<comp-one v-if="activeComp"></comp-one>
</div>
</template>
<script>
export default {
data() {
return {
activeComp: true
};
},
updated() {
console.log("The component is updated!");
}
};
<\/script>
هشدار: تغییر مستقیم صفحه در updated حلقه بی نهایت می سازد.
<template>
<h1>The 'updated' Lifecycle Hook</h1>
<p>This example triggers a loop.</p>
<button @click="this.activeComp = !this.activeComp">Add/Remove Component</button>
<div>
<comp-one v-if="activeComp"></comp-one>
</div>
<div>{{ text }}</div>
</template>
<script>
export default {
data() {
return {
activeComp: true,
text: "Hello, "
};
},
updated() {
this.text += "hi, ";
}
};
<\/script>
beforeUnmount و unmounted: خداحافظی با DOM
beforeUnmount درست قبلِ حذف اجرا می شود. unmounted بعد از حذف اجرا می شود.
<template>
<h2>Component</h2>
<p ref="pEl">Strawberries!</p>
</template>
<script>
export default {
beforeUnmount() {
alert("beforeUnmount: " + this.$refs.pEl.innerHTML);
}
};
<\/script>
<template>
<h2>Component</h2>
<p>When unmounted, alert shows.</p>
</template>
<script>
export default {
unmounted() {
alert("The component is removed (unmounted)!");
}
};
<\/script>
errorCaptured: خطای فرزند را بگیر
اگر در فرزند خطا شود، والد می تواند با errorCaptured آن را بگیرد و گزارش کند.
<template>
<h1>The 'errorCaptured' Lifecycle Hook</h1>
<div>
<comp-one></comp-one>
</div>
</template>
<script>
export default {
errorCaptured() {
alert("An error occurred");
}
};
<\/script>
activated / deactivated: وقتی کش فعال است
با <KeepAlive> کامپوننت کش می شود. آنگاه activated و deactivated به جای حذف کامل، اجرا می شوند.
<template>
<h1>The 'activated' Lifecycle Hook</h1>
<p>Check caching with <KeepAlive>.</p>
<button @click="this.activeComp = !this.activeComp">Include component</button>
<div>
<KeepAlive>
<comp-one v-if="activeComp"></comp-one>
</KeepAlive>
</div>
</template>
<script>
export default {
data() {
return {
activeComp: false
};
}
};
<\/script>
گام های عملی
- کارهای داده ای را در
createdانجام بده. - کارهای DOM را در
mountedانجام بده. - در
updatedتغییر DOM نده. - قبل حذف از
beforeUnmountبهره ببر.
جمع بندی سریع
beforeCreateهنوز هیچ چیز آماده نیست.createdداده ها آماده اند، DOM نه.mountedبهترین زمان کار با DOM است.updatedرا فقط برای گزارش استفاده کن.beforeUnmountوunmountedبرای خداحافظی اند.