Sifat yang dikira
Dokumentasi rasmi Vue3 mempunyai penerangan ini untuk sifat yang dikira:
Untuk sebarang respons yang mengandungi Untuk logik kompleks data formula , kita harus menggunakan sifat yang dikira .
Sifat yang dikira hanya akan dinilai semula apabila kebergantungan reaktif yang berkaitan berubah.
Daripada huraian di atas, keperluan untuk atribut yang dikira boleh difahami dengan jelas Atribut yang dikira mengira data responsif (huraian mesyuarat 1), dan hasil pengiraan hendaklah dicache (mesyuarat. penerangan 2) ). Mari kita laksanakannya satu demi satu, bermula dengan mencipta harta yang dikira menggunakan computed
.
function effect(fn) { // 副作用函数 const effectFn = () => { cleanup(effectFn) activeEffect = effectFn effectStack.push(effectFn) fn() effectStack.pop() activeEffect = effectStack[effectStack.length - 1] } effectFn.deps = [] effectFn() } ... const data = { foo: 1, bar: 2 } const obj = new Proxy(data, { // 响应式对象 get(target, key) { track(target, key) return target[key] }, set(target, key, newValue) { target[key] = newValue trigger(target, key) return true } }) ... const sumRes = computed(() => obj.foo + obj.bar) // (1) console.log(sumRes.value)
Pada (1), kami hanya menulis fungsi untuk mengira atribut Untuk merealisasikan fungsi membaca nilai atribut yang dikira melalui sumRes.value
, apabila melaksanakan atribut yang dikira, adalah perlu untuk mengembalikan. objek dan lulus objek get
mencetuskan fungsi kesan sampingan.
function computed(getter) { const effectFn = effect(getter) const obj = { get value() { return effectFn() } } return obj }
Tetapi fungsi ini jelas tidak boleh dilaksanakan Ini kerana apabila kami melaksanakan effect
tadi, kami perlu melaksanakan fungsi kesan sampingan secara langsung tanpa memberikan nilai pulangan. Tanpa nilai pulangan, computed
secara semula jadi tidak boleh mendapatkan hasil pelaksanaan effect
. Oleh itu, apabila menggunakan effect
dalam sifat yang dikira, fungsi kesan sampingan perlu dikembalikan kepada sifat yang dikira, dan sifat yang dikira menentukan masa untuk melaksanakannya, dan bukannya dilaksanakan serta-merta oleh effect
(iaitu, malas melaksanakan ) .
Untuk mencapai ini, anda perlu menambah suis effect
ke lazy
Memandangkan kami mungkin perlu mengkonfigurasi ciri lain untuk effect
pada masa hadapan, kami menggunakan objek options
. untuk merangkum suis ini.
function effect(fn, options = {}) { const effectFn = () => { cleanup(effectFn) activeEffect = effectFn effectStack.push(effectFn) const res = fn() // (1) effectStack.pop() activeEffect = effectStack[effectStack.length - 1] return res // (2) } effectFn.deps = [] effectFn.options = options // (3) if (!options.lazy) { // (4) effectFn() } return effectFn // (5) }
Kami meletakkan suis lazy
di (4), dan fungsi kesan sampingan yang tidak memerlukan pelaksanaan malas juga akan dilaksanakan secara automatik. Hasil daripada fungsi kesan sampingan dikembalikan pada (1) (2) (5) untuk pelaksanaan malas. Pada masa yang sama, options
diturunkan pada (3) untuk memastikan bahawa apabila effect
bersarang, fungsi kesan sampingan juga akan melaksanakan tingkah laku yang diharapkan. Berdasarkan pengubahsuaian effect
di atas, kami menetapkan suis computed
dalam lazy
.
function computed(getter) { const effectFn = effect(getter, { lazy: true }) const obj = { get value() { // (6) return effectFn() } } return obj } const sumRes = computed(() => obj.foo + obj.bar)
Seperti yang dapat dilihat dari rajah di atas, kami telah melaksanakan penerangan 1, iaitu, menggunakan sifat terkira untuk mengira data responsif, apabila nilai data responsif berubah , nilai atribut yang dikira juga akan berubah dengan sewajarnya. Tetapi memerhatikan perkara (6) kod di atas, tidak sukar untuk mencari bahawa tidak kira apa keadaan sekalipun, selagi nilai sumRes.value
dibaca, fungsi kesan sampingan akan dicetuskan, menyebabkan ia dilaksanakan semula mungkin tidak perlu. Jadi seterusnya, kami cuba melaksanakan penerangan 2, menyimpan cache hasil atribut yang dikira.
Mari kita mulakan dengan yang paling mudah Kami menggunakan pembolehubah value
untuk menyimpan cache nilai yang dikira terakhir dan menambah suis dirty
untuk merekodkan sama ada fungsi kesan sampingan perlu dicetuskan semula.
function computed(getter) { let value let dirty = true const effectFn = effect(getter, { lazy: true }) const obj = { get value() { if(dirty) { value = effectFn() dirty = false } return value } } return obj }
Selepas pengubahsuaian, nilai cache akan berkuat kuasa. Tetapi ini mewujudkan BUG yang jelas Apabila nilai dirty
ditetapkan kepada false
, ia tidak lagi boleh ditukar kepada true
Ini bermakna tidak kira bagaimana data responsif obj.bar
dan obj.foo
Berubah, nilai atribut yang dikira sentiasa boleh menjadi nilai cache value
, seperti yang ditunjukkan dalam rajah di bawah.
Untuk menyelesaikan masalah ini, kita memerlukan cara untuk menukar obj.bar apabila nilai obj.foo
atau sumRes.value
berubah nilai suis ditetapkan kepada dirty
. Diilhamkan oleh pemuatan malas sebelum ini, kami cuba melihat sama ada kami boleh mencapai fungsi ini dengan mengkonfigurasi true
. options
const obj = new Proxy(data, { get(target, key) { track(target, key) return target[key] }, set(target, key, newValue) { target[key] = newValue trigger(target, key) return true } })Mari kita ingat keseluruhan proses objek responsif Apabila data dalam objek responsif diubah suai,
dilaksanakan untuk mencetuskan fungsi kesan sampingan yang dikumpul. Dalam sifat yang dikira, kita tidak lagi perlu mencetuskan fungsi kesan sampingan secara automatik. Jadi wajar untuk berfikir, bolehkah saya menggantikan trigger
dengan dirty
di tempat ini? Mengikuti idea ini, kami mula-mula mengubah suai true
. trigger
function trigger(target, key) { const propsMap = objsMap.get(target) if(!propsMap) return const fns = propsMap.get(key) const otherFns = new Set() fns && fns.forEach(fn => { if(fn !== activeEffect) { otherFns.add(fn) } }) otherFns.forEach(fn => { if(fn.options.scheduler) { // (7) fn.options.scheduler() } else { fn() } }) }Mengikut idea sebelumnya, kami menambah pertimbangan di (7 Jika item konfigurasi
fungsi kesan sampingan fn
mengandungi fungsi options
, kami akan melaksanakan scheduler
sebaliknya fungsi kesan sampingan scheduler
. Kami memanggil fn
di sini scheduler
penjadual. Sejajar dengan itu, kami menambah penjadual dalam atribut yang dikira.
function computed(getter) { let value let dirty = true const effectFn = effect(getter, { lazy: true, scheduler() { // (8) dirty = true } }) const obj = { get value() { if(dirty) { value = effectFn() dirty = false } return value } } return obj }
在(8)处我们添加了调度器。添加调度器后,让我们再来串一下整个流程,当响应式数据被修改时,才会执行trigger
函数。由于我们传入了调度器,因此trigger
函数在执行时不再触发副作用函数,转而执行调度器,此时dirty
开关的值变为了true
。当程序再往下执行时,由于dirty
已经变为true
,副作用函数就可以正常被手动触发。效果如下图所示。
到这里为止,计算属性在功能上已经实现完毕了,让我们尝试完善它。在Vue中,当计算属性中的响应式数据被修改时,计算属性值会同步更改,进而重新渲染,并在页面上更新。渲染函数也会执行effect
,为了说明问题,让我们使用effect
简单的模拟一下。
const sumRes = computed(() => obj.foo + obj.bar) effect(() => console.log('sumRes =', sumRes.value))
这里我们的预期是当obj.foo
或obj.bar
改变时,effect
会自动重新执行。这里存在的问题是,正常的effect
嵌套可以被自动触发(这点我们在上一篇博客中已经实现了),但sumRes
包含的effect
仅会在被读取value
时才会被get
触发执行,这就导致响应式数据obj.foo
与obj.bar
无法收集到外部的effect
,收集不到的副作用函数,自然无法被自动触发。
function computed(getter) { let value let dirty = true const effectFn = effect(getter, { lazy: true, scheduler() { dirty = true trigger(obj, 'value') // (9) } }) const obj = { get value() { if(dirty) { value = effectFn() dirty = false } track(obj, 'value') // (10) return value } } return obj }
在(10)处我们手动收集了副作用函数,并当响应式数据被修改时,触发它们。
使用微任务优化调度器
在设计调度器时,我们忽略了一个潜在的问题。
还是先来看一个例子:
effect(() => console.log(obj.foo)) for(let i = 0; i < 1e5; i++) { obj.foo++ }
随着响应式数据obj.foo
被不停修改,副作用函数也被不断重复执行,在明显的延迟之后,控制台打印出了大量的数据。但在前端的实际开发中,我们往往只关心最终结果,拿到结果显示在页面上。在这种条件下,我们如何避免副作用函数被重复执行呢?
const jobQueue = new Set() // (11) const p = Promise.resolve() // (12) let isFlushing = false // (13) function flushJob() { // (14) if (isFlushing) return isFlushing = true p.then(() => { jobQueue.forEach(job => { job() }) }).finally(() => { isFlushing = false }) }
这里我们的思路是使用微任务队列来进行优化。(11)处我们定义了一个Set
作为任务队列,(12)处我们定义了一个Promise
来使用微任务。精彩的部分来了,我们的思路是将副作用函数放入任务队列中,由于任务队列是基于Set
实现的,因此,重复的副作用函数仅会保留一个,这是第一点。接着,我们执行flushJob()
,这里我们巧妙的设置了一个isFlushing
开关,这个开关保证了被微任务包裹的任务队列在一次事件循环中只会执行一次,而执行的这一次会在宏任务完成之后触发任务队列中所有不重复的副作用函数,从而直接拿到最终结果,这是第二点。按照这个思路,我们在effect
中添加调度器。
effect(() => { console.log(obj.foo) }, { scheduler(fn) { jobQueue.add(fn) flushJob() } })
需要注意的是,浏览器在执行微任务时,会依次处理微任务队列中的所有微任务。因此,微任务在执行时会阻塞页面的渲染。因此,在实践中需避免在微任务队列中放置过于繁重的任务,以免导致性能问题。
Atas ialah kandungan terperinci Cara melaksanakan sifat terkira Vue3. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Vue.js adalah kerangka depan, dan rangka kerja belakang digunakan untuk mengendalikan logik sisi pelayan. 1) Vue.js memberi tumpuan kepada membina antara muka pengguna dan memudahkan pembangunan melalui pengikatan data komponen dan responsif. 2) Rangka kerja back-end seperti Express dan Django mengendalikan permintaan HTTP, operasi pangkalan data dan logik perniagaan, dan dijalankan di pelayan.

Vue.js disepadukan dengan tumpuan teknologi front-end untuk meningkatkan kecekapan pembangunan dan pengalaman pengguna. 1) Alat Pembinaan: Mengintegrasikan dengan Webpack dan Rollup untuk mencapai pembangunan modular. 2) Pengurusan Negeri: Bersepadu dengan VUEX untuk menguruskan status aplikasi yang kompleks. 3) Routing: Mengintegrasikan dengan Vuerouter untuk merealisasikan penghalaan aplikasi tunggal halaman. 4) Preprocessor CSS: Menyokong SASS dan kurang untuk meningkatkan kecekapan pembangunan gaya.

Netflix memilih React untuk membina antara muka penggunanya kerana reka bentuk komponen React dan mekanisme DOM maya dapat mengendalikan antara muka yang kompleks dan kemas kini yang kerap. 1) Reka bentuk berasaskan komponen membolehkan Netflix memecah antara muka ke dalam widget yang boleh diurus, meningkatkan kecekapan pembangunan dan pemeliharaan kod. 2) Mekanisme DOM maya memastikan kelancaran dan prestasi tinggi antara muka pengguna Netflix dengan meminimumkan operasi DOM.

Vue.js disukai oleh pemaju kerana mudah digunakan dan berkuasa. 1) Sistem pengikat data responsifnya secara automatik mengemas kini paparan. 2) Sistem komponen meningkatkan kebolehgunaan semula dan mengekalkan kod. 3) Ciri -ciri pengkomputeran dan pendengar meningkatkan kebolehbacaan dan prestasi kod. 4) Menggunakan vuedevtools dan memeriksa kesilapan konsol adalah teknik debugging biasa. 5) Pengoptimuman Prestasi termasuk penggunaan atribut utama, atribut yang dikira dan komponen-komponen Alive. 6) Amalan terbaik termasuk penamaan komponen yang jelas, penggunaan komponen fail tunggal dan penggunaan cangkuk kitaran hidup yang rasional.

Vue.js adalah rangka kerja JavaScript yang progresif yang sesuai untuk membina aplikasi front-end yang cekap dan boleh dipelihara. Ciri -ciri utamanya termasuk: 1. Pengikatan data responsif, 2. Pembangunan Komponen, 3. Dom maya. Melalui ciri -ciri ini, Vue.js memudahkan proses pembangunan, meningkatkan prestasi aplikasi dan mengekalkan, menjadikannya sangat popular dalam pembangunan web moden.

Vue.js dan bertindak balas masing -masing mempunyai kelebihan dan kekurangan mereka sendiri, dan pilihannya bergantung kepada keperluan projek dan keadaan pasukan. 1) vue.js sesuai untuk projek kecil dan pemula kerana kesederhanaan dan mudah digunakan; 2) React sesuai untuk projek besar dan UI yang kompleks kerana reka bentuk ekosistem dan komponennya yang kaya.

Vue.js meningkatkan pengalaman pengguna melalui pelbagai fungsi: 1. Sistem responsif menyedari maklum balas data masa nyata; 2. Pembangunan komponen meningkatkan kebolehgunaan semula kod; 3. Vuerouter menyediakan navigasi lancar; 4. Data dinamik mengikat dan animasi peralihan meningkatkan kesan interaksi; 5. Mekanisme pemprosesan ralat memastikan maklum balas pengguna; 6. Pengoptimuman prestasi dan amalan terbaik meningkatkan prestasi aplikasi.

Peranan vue.js dalam pembangunan web adalah bertindak sebagai rangka kerja JavaScript yang progresif yang memudahkan proses pembangunan dan meningkatkan kecekapan. 1) Ia membolehkan pemaju memberi tumpuan kepada logik perniagaan melalui pengikatan data yang responsif dan pembangunan komponen. 2) Prinsip kerja Vue.js bergantung kepada sistem responsif dan DOM maya untuk mengoptimumkan prestasi. 3) Dalam projek sebenar, adalah amalan biasa untuk menggunakan VUEX untuk menguruskan keadaan global dan mengoptimumkan respons data.


Alat AI Hot

Undresser.AI Undress
Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover
Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool
Gambar buka pakaian secara percuma

Clothoff.io
Penyingkiran pakaian AI

Video Face Swap
Tukar muka dalam mana-mana video dengan mudah menggunakan alat tukar muka AI percuma kami!

Artikel Panas

Alat panas

ZendStudio 13.5.1 Mac
Persekitaran pembangunan bersepadu PHP yang berkuasa

SublimeText3 versi Inggeris
Disyorkan: Versi Win, menyokong gesaan kod!

Notepad++7.3.1
Editor kod yang mudah digunakan dan percuma

Penyesuai Pelayan SAP NetWeaver untuk Eclipse
Integrasikan Eclipse dengan pelayan aplikasi SAP NetWeaver.

Versi Mac WebStorm
Alat pembangunan JavaScript yang berguna
