Yang manakah mempunyai keutamaan yang lebih tinggi, v-for atau v-if? Artikel berikut akan menerangkan keutamaan v-for
dan v-if
daripada contoh sebenar dan kod sumber saya percaya anda akan mendapat pencerahan selepas membaca ini.
1. Tidak digalakkan menggunakan v-for dan v-if pada masa yang sama. (Belajar perkongsian video: tutorial video vue)
2. v-for mempunyai keutamaan yang lebih tinggi daripada v-if dalam vue2. Oleh kerana vue2 akan memproses v-for dahulu dan kemudian v-if apabila menyusun templat, fungsi pemaparan yang dijana akan mula-mula melaksanakan gelung, dan kemudian melaksanakan penghakiman bersyarat di dalam gelung.
3. Masalah yang disebabkan oleh ini ialah
Untuk Senario 1: <li v-for="user in users" v-if="user.show">
Setiap kali kami membuat semula, kami perlu merentasi semula keseluruhan senarai. Sebenarnya, kami Hanya sebahagian daripada senarai yang diperlukan, yang membazirkan prestasi. Pendekatan yang disyorkan ialah menapis bahagian yang kita perlukan melalui atribut yang dikira dan kemudian menjadikannya, yang lebih cekap.
Untuk senario 2: <li v-for="user in users" v-if="globalShow">
Malah, jika penghakiman globalShow adalah palsu, gelung tidak perlu dilaksanakan, tetapi kini ia digunakan dengan v-if, dan ia mesti dilaksanakan tanpa mengira sama ada globalShow adalah benar. Pendekatan yang disyorkan ialah memindahkan v-jika ke atas bekas ul.
4. Perlu diingatkan bahawa untuk perubahan pecah vue3, v-if mempunyai keutamaan yang lebih tinggi daripada v-for dalam vue3, jadi jika ia digunakan pada masa yang sama, untuk senario 1, pada masa ini masa pengguna belum lagi, v -if="user.show" akan melaporkan ralat
5 Secara amnya, jika kami menggunakan eslint, ia juga akan melaporkan ralat kepada kami /no-use-v-if-with-v- for
Contohnya: Templat berikut akan menjana fungsi pemaparan berikut
<ul> <li v-for="user in users" v-if="user.isActive" :key="user.id"> {{ user.name }} </li> </ul>
The fungsi rendering yang dijana adalah seperti berikut
with(this) { return _c('ul', _l((users), function (user) { return (user.isActive) ? _c('li', user.name) : _e() }), 0) }
Seperti yang dapat dilihat daripada fungsi rendering yang dijana di atas, _l
traversal user
akan dilaksanakan terlebih dahulu, dan penghakiman bersyarat akan dilakukan di dalam
kod sumber untuk memproses v-if dan v-for
src/compiler/index.js
// 模板解析,生成ast树 const ast = parse(template.trim(), options) if (options.optimize !== false) { optimize(ast, options) } const code = generate(ast, options)
Jana kod berdasarkan ast , ast yang dijana dipermudahkan seperti berikut
// 可以看出v-for和v-if都解析出来了 ast = { 'type': 1, 'tag': 'ul', 'attrsList': [], 'attrsMap': {}, 'children': [{ 'type': 1, 'tag': 'li', 'attrsList': [], 'attrsMap': { 'v-for': 'user in users', 'v-if': 'user.show' }, // v-if解析出来的属性 'if': 'user.show', 'ifConditions': [{ 'exp': 'user.show', 'block': // 指向el自身 }], // v-for解析出来的属性 'for': 'users', 'alias': 'user', 'iterator1': 'index', 'parent': // 指向其父节点 'children': [ 'type': 2, 'expression': '_s(user)' 'text': '{{user}}', 'tokens': [ {'@binding':'user'}, ] ] }] }
compiler/codegen/index.js
// generate 调用 genElement const code = ast ? genElement(ast, state) : '_c("div")' // genElement里面的处理 if (el.staticRoot && !el.staticProcessed) { return genStatic(el, state) } else if (el.once && !el.onceProcessed) { return genOnce(el, state) // 从这可以看出来,先执行genFor,处理v-for指令,在genFor里面会递归调用genElement,继续处理v-if,genFor会将forProcessed设为true,这样下次进来的时候就不会处理for了 } else if (el.for && !el.forProcessed) { return genFor(el, state) } else if (el.if && !el.ifProcessed) { return genIf(el, state) } else if (el.tag === 'template' && !el.slotTarget && !state.pre) { return genChildren(el, state) || 'void 0' } else if (el.tag === 'slot') { return genSlot(el, state) } else { // 最后这里处理标签等 const children = el.inlineTemplate ? null : genChildren(el, state, true) code = `_c('${el.tag}'${ data ? `,${data}` : '' // data }${ children ? `,${children}` : '' // children })` } // genFor的代码 const exp = el.for // 对应上面ast的 for: users const alias = el.alias // alias: user // iterator1 对应v-for的(item,key,index) in items的key // iterator2 对应的是index // 通常我们遍历数组 key就是index // 假如我们遍历的是对象 key就是对象的key,index就是遍历的索引 const iterator1 = el.iterator1 ? `,${el.iterator1}` : '' const iterator2 = el.iterator2 ? `,${el.iterator2}` : '' el.forProcessed = true // 下次递归调用genElement的时候就不会重复处理v-for了 return `${altHelper || '_l'}((${exp}),` + `function(${alias}${iterator1}${iterator2}){` // 这里处理完了v-for,递归调用genElement继续处理v-if `return ${(altGen || genElement)(el, state)}` + '})'
最终会生成类似如下的代码返回出去
_l((users), function(user, index) { // 如果有v-if 前面就会有个条件判断,如user.isActive return (user.isActive) ? _c('li', user.name) : _e() });
(Perkongsian video pembelajaran: web pembangunan bahagian hadapan, Video pengaturcaraan asas)
Atas ialah kandungan terperinci Perbandingan keutamaan: Manakah lebih tinggi, v-untuk atau v-jika?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!