ฉันอ่านเอกสาร แต่ไม่เข้าใจ ฉันรู้ว่าข้อมูลใดคำนวณดูวิธีการทำ แต่สิ่งที่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);
โหลดเบราว์เซอร์ใหม่ คุณจะเห็นก่อนที่คุณจะเห็นTwo
Three
ตรวจสอบซอนี้เพื่อดูสด
นั่นเป็นเพราะ 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
ในกรณีที่คุณจะใช้ เอกสารที่นี่