ฉันอ่านเอกสาร แต่ไม่เข้าใจ ฉันรู้ว่าข้อมูลใดคำนวณดูวิธีการทำ แต่สิ่งที่nextTick()ใช้สำหรับ vuejs?
const nextTick = (callback, context) => { setTimeout(callback.bind(context), 0); };?
ฉันอ่านเอกสาร แต่ไม่เข้าใจ ฉันรู้ว่าข้อมูลใดคำนวณดูวิธีการทำ แต่สิ่งที่nextTick()ใช้สำหรับ vuejs?
const nextTick = (callback, context) => { setTimeout(callback.bind(context), 0); };?
คำตอบ:
nextTickช่วยให้คุณสามารถทำบางสิ่งได้หลังจากที่คุณเปลี่ยนข้อมูลและ VueJS ได้อัปเดต DOM ตามการเปลี่ยนแปลงข้อมูลของคุณ แต่ก่อนที่เบราว์เซอร์จะแสดงการเปลี่ยนแปลงเหล่านั้นบนหน้า
โดยปกติdevs ใช้ฟังก์ชัน JavaScript ดั้งเดิม setTimeoutเพื่อให้ได้ลักษณะการทำงานที่คล้ายคลึงกัน แต่การใช้การsetTimeoutยกเลิกการควบคุมไปยังเบราว์เซอร์ก่อนที่จะให้การควบคุมกลับมาหาคุณผ่านการโทรกลับของคุณ
สมมติว่าคุณเปลี่ยนข้อมูลบางส่วน Vue อัปเดต DOM ตามข้อมูล โปรดทราบว่าเบราว์เซอร์ยังไม่แสดงการเปลี่ยนแปลง DOM บนหน้าจอ หากคุณใช้ระบบnextTickจะโทรกลับทันที จากนั้นเบราว์เซอร์จะอัปเดตเพจ หากคุณใช้การsetTimeoutโทรกลับของคุณจะถูกโทรหาในตอนนี้เท่านั้น
คุณสามารถเห็นภาพพฤติกรรมนี้ได้โดยการสร้างส่วนประกอบเล็ก ๆ ดังต่อไปนี้:
<template>
<div class="hello">
{{ msg }}
</div>
</template>
<script>
export default {
name: 'HelloWorld',
data() {
return {
msg: 'One'
}
},
mounted() {
this.msg = 'Two';
this.$nextTick(() => {
this.msg = 'Three';
});
}
}
</script>
เรียกใช้เซิร์ฟเวอร์ภายในของคุณ คุณจะเห็นข้อความThreeถูกแสดง
ตอนนี้แทนที่ของคุณthis.$nextTickด้วยsetTimeout
setTimeout(() => {
this.msg = 'Three';
}, 0);
โหลดเบราว์เซอร์ใหม่ คุณจะเห็นก่อนที่คุณจะเห็นTwoThree
ตรวจสอบซอนี้เพื่อดูสด
นั่นเป็นเพราะ Vue อัปเดต DOM เป็นTwoให้การควบคุมเบราว์เซอร์ เบราว์เซอร์ปรากฏTwoขึ้น จากนั้นโทรกลับ Vue อัปเดต DOM เป็นThree. ซึ่งเบราว์เซอร์แสดงอีกครั้ง.
ด้วยnextTick. Vue udpated DOM เป็นTwo. โทรกลับของคุณ Vue อัปเดต DOM เป็นThree. จากนั้นให้การควบคุมเบราว์เซอร์ และเบราว์เซอร์จะปรากฏThreeขึ้น
หวังว่ามันจะชัดเจน
เพื่อให้เข้าใจถึงวิธีการดำเนิน Vue นี้คุณต้องเข้าใจแนวคิดของเหตุการณ์ห่วงและmicrotasks
เมื่อคุณมีแนวคิดเหล่านี้ชัดเจน (ER), ตรวจสอบรหัสแหล่งสำหรับ nextTick
this.name = 'foo'หรือคุณกำลังอ้างถึงการแทรกองค์ประกอบ html ในหน้า?
this.name = 'foo'vue จะอัปเดตโมเดลอ็อบเจ็กต์เอกสารเพื่อแสดงถึงการเปลี่ยนแปลงที่เกิดขึ้นกับข้อมูลตามเทมเพลตและฟังก์ชันที่คุณกำหนดค่า
เนื้อหานี้นำมาจาก By Adrià Fontcuberta
เอกสาร Vue กล่าวว่า:
Vue.nextTick ([เรียกกลับบริบท])
เลื่อนการเรียกกลับเพื่อดำเนินการหลังจากรอบการอัปเดต DOM ถัดไป ใช้ทันทีหลังจากที่คุณเปลี่ยนข้อมูลบางส่วนเพื่อรอการอัปเดต DOM
อืม ... ถ้าตอนแรกรู้สึกกลัวก็ไม่ต้องกังวลฉันจะพยายามอธิบายให้เรียบง่ายที่สุด แต่ก่อนอื่นมี 2 สิ่งที่คุณควรรู้:
การใช้งานมันผิดปกติ เช่นเดียวกับหนึ่งในการ์ดเวทมนตร์สีเงินเหล่านั้น ฉันเขียนVueแอพหลายตัวแล้วและเจอ nextTick () หนึ่งครั้งหรือสองครั้ง
เข้าใจง่ายขึ้นเมื่อคุณได้เห็นกรณีการใช้งานจริง หลังจากที่คุณได้แนวคิดแล้วความกลัวจะหายไปและคุณจะมีเครื่องมือที่มีประโยชน์อยู่ใต้เข็มขัดของคุณ
ไปกันเลยดีกว่า
เราเป็นโปรแกรมเมอร์ไม่ใช่เหรอ? เราจะใช้วิธีการแบ่งแยกและพิชิตอันเป็นที่รักของเราเพื่อพยายามแปลคำอธิบายที.nextTick()ละนิด เริ่มต้นด้วย:
เลื่อนการโทรกลับ
ตกลงตอนนี้เรารู้แล้วว่ายอมรับการติดต่อกลับ จึงมีลักษณะดังนี้:
Vue.nextTick(function () {
// do something cool
});
เยี่ยมมาก การโทรกลับนี้ถูกเลื่อนออกไป (นี่คือสิ่งที่คนนับพันปีพูดว่าล่าช้า) จนถึง ...
รอบการอัปเดต DOM ถัดไป
ตกลง. เรารู้ว่าวูดำเนินการปรับปรุง DOM ถ่ายทอดสด คุณลักษณะนี้มีวิธีการ "จัดเก็บ" การอัปเดตเหล่านี้ไว้จนกว่าจะจำเป็นต้องใช้ สร้างคิวการอัปเดตและล้างข้อมูลเมื่อจำเป็น จากนั้น DOM จะถูก "แก้ไข" และอัปเดตเป็นเวอร์ชันล่าสุด
อะไร?
ให้ฉันลองอีกครั้ง: ลองนึกภาพส่วนประกอบของคุณทำบางสิ่งที่สำคัญและชาญฉลาดเช่นthis.potatoAmount = 3.Vue จะไม่แสดงผลส่วนประกอบอีกครั้ง (และ DOM) โดยอัตโนมัติ มันจะจัดคิวการแก้ไขที่จำเป็น จากนั้นใน "ติ๊ก" ถัดไป (เช่นเดียวกับนาฬิกา) คิวจะถูกล้างและการอัปเดตจะถูกนำไปใช้ ธาดา!
ตกลง! ดังนั้นเราจึงรู้ว่าเราสามารถใช้nextTick()เพื่อส่งผ่านฟังก์ชันการเรียกกลับที่ดำเนินการได้ทันทีหลังจากตั้งค่าข้อมูลและ DOM ได้รับการอัปเดต
อย่างที่บอกไปก่อนหน้านี้…ไม่บ่อยนัก แนวทาง "การไหลของข้อมูล" ที่ขับเคลื่อน Vue, React และอีกวิธีหนึ่งจาก Google ซึ่งฉันจะไม่พูดถึงทำให้มันไม่จำเป็นเกือบตลอดเวลา อย่างไรก็ตามบางครั้งเราต้องรอให้องค์ประกอบบางอย่างปรากฏ / หายไป / แก้ไขใน DOM นี่คือตอนที่ nextTick มีประโยชน์
ใช้ทันทีหลังจากที่คุณเปลี่ยนข้อมูลบางส่วนเพื่อรอการอัปเดต DOM
เป๊ะ! นี่คือคำจำกัดความชิ้นสุดท้ายที่ Vue docs ให้กับเรา ภายในการโทรกลับของเรา DOM ได้รับการอัปเดตเพื่อให้เราสามารถโต้ตอบกับเวอร์ชันที่ "อัปเดตที่สุด" ได้
พิสูจน์สิ
ตกลงตกลง. ดูคอนโซลและคุณจะเห็นว่าค่าของข้อมูลของเราได้รับการอัปเดตภายในการเรียกกลับของ nextTick เท่านั้น:
const example = Vue.component('example', {
template: '<p>{{ message }}</p>',
data: function () {
return {
message: 'not updated'
}
},
mounted () {
this.message = 'updated'
console.log(
'outside nextTick callback:', this.$el.textContent
) // => 'not updated'
this.$nextTick(() => {
console.log(
'inside nextTick callback:', this.$el.textContent
) // => 'not updated'
})
}
})
new Vue({
el: '#app',
render: h => h(example)
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.10/vue.js"></script>
<div id="app"></div>
กรณีการใช้งาน
nextTickลองที่จะกำหนดกรณีการใช้งานบางอย่างมีประโยชน์สำหรับ
ลองนึกภาพว่าคุณต้องดำเนินการบางอย่างเมื่อต่อส่วนประกอบ แต่! ไม่เพียง แต่ส่วนประกอบเท่านั้น คุณต้องรอจนกว่าลูกทั้งหมดจะติดตั้งและพร้อมใช้งานใน DOM ประณาม! ขอเกี่ยวของเราไม่รับประกันว่าโครงสร้างส่วนประกอบทั้งหมดจะแสดงผล
หากเพียงเรามีเครื่องมือสำหรับรอการอัปเดต DOM รอบถัดไป ...
ฮ่าฮ่า:
mounted() {
this.$nextTick(() => {
// The whole view is rendered, so I can safely access or query
// the DOM. ¯\_(ツ)_/¯
})
}
โดยสังเขป
ดังนั้น: nextTickเป็นวิธีที่สะดวกสบายในการเรียกใช้ฟังก์ชันหลังจากที่ตั้งค่าข้อมูลและ DOM ได้รับการอัปเดตแล้ว
คุณต้องรอ DOM อาจเป็นเพราะคุณต้องทำการเปลี่ยนแปลงบางอย่างหรือคุณต้องรอให้ไลบรารีภายนอกโหลดข้อมูล จากนั้นใช้ nextTick
บางคนยังใช้ nextTick ในการทดสอบหน่วยเพื่อให้แน่ใจว่าข้อมูลได้รับการอัปเดตแล้ว ด้วยวิธีนี้พวกเขาสามารถทดสอบ "เวอร์ชันอัปเดต" ของคอมโพเนนต์
Vue.nextTick () หรือ vm. $ nextTick ()?
ไม่ต้องกังวล. ทั้งสอง (เกือบ) เหมือนกัน Vue.nextTick()หมายถึงวิธีการ API ส่วนกลางในขณะที่vm.$nextTick()เป็นวิธีการอินสแตนซ์ ข้อแตกต่างเพียงอย่างเดียวคือvm.$nextTickไม่ยอมรับบริบทเป็นพารามิเตอร์ที่สอง มันถูกผูกไว้กับthis(หรือที่เรียกว่าอินสแตนซ์เอง)
ชิ้นสุดท้ายของความเย็น
สังเกตว่าnextTickส่งกลับ a Promiseเพื่อให้เราสามารถใช้async/awaitและปรับปรุงตัวอย่างได้อย่างเต็มที่:
async mounted () {
this.message = 'updated'
console.log(this.$el.textContent) // 'not updated'
await this.$nextTick()
console.log(this.$el.textContent) // 'updated'
}
StackOverflowผลลัพธ์ของ Google มักจะเป็นอันดับแรก SO เป็นสถานที่สำหรับค้นหาคำตอบโดยพฤตินัย แต่มีแหล่งข้อมูลดีๆมากมายบนอินเทอร์เน็ตซึ่งอาจไม่ปรากฏในผลการค้นหา ดังนั้นฉันจึงใช้เวลาเกือบครึ่งชั่วโมงสำหรับคำตอบนี้ไม่ใช่แค่การคัดลอกตามที่คุณระบุผู้เขียนได้รับเครดิตตั้งแต่เริ่มต้น ถ้าไม่ชอบโพสต์ก็โอเค แต่คุณควรเคารพงานของผู้อื่น
Next Tick โดยทั่วไปจะช่วยให้คุณสามารถรันโค้ดได้หลังจากที่ vue แสดงผลคอมโพเนนต์อีกครั้งเมื่อคุณทำการเปลี่ยนแปลงบางอย่างกับคุณสมบัติรีแอคทีฟ (ข้อมูล)
// modify data
vm.msg = 'Hello'
// DOM not updated yet
Vue.nextTick(function () {
// this function is called when vue has re-rendered the component.
})
// usage as a promise (2.1.0+, see note below)
Vue.nextTick()
.then(function () {
// this function is called when vue has re-rendered the component.
})
จากเอกสาร Vue.js:
เลื่อนการเรียกกลับเพื่อดำเนินการหลังจากรอบการอัปเดต DOM ถัดไป ใช้ทันทีหลังจากที่คุณเปลี่ยนข้อมูลบางส่วนเพื่อรอการอัปเดต DOM
เพื่อให้คำตอบของ Pranshat เกี่ยวกับความแตกต่างระหว่างการใช้ nextTick และ setTimeout ชัดเจนยิ่งขึ้นฉันได้แยกเสียงซอของเขา: ที่นี่
mounted() {
this.one = "One";
setTimeout(() => {
this.two = "Two"
}, 0);
//this.$nextTick(()=>{
//this.two = "Two"
//})}
คุณจะเห็นในซอว่าเมื่อใช้ setTimeOut ข้อมูลเริ่มต้นจะกะพริบสั้น ๆ เมื่อประกอบส่วนประกอบก่อนที่จะปรับการเปลี่ยนแปลง ในขณะที่เมื่อใช้ nextTick ข้อมูลจะถูกแย่งชิงเปลี่ยนแปลงก่อนที่จะแสดงผลไปยังเบราว์เซอร์ ดังนั้นเบราว์เซอร์จึงแสดงข้อมูลที่อัปเดตโดยที่ไม่มีความรู้เรื่องเก่าเลย หวังว่าจะเคลียร์ทั้งสองแนวคิดในบัดดล
nextTickในกรณีที่คุณจะใช้ เอกสารที่นี่