中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

v-for和v-if的優先級哪個更高

發布時間:2022-08-30 09:47:52 來源:億速云 閱讀:264 作者:iii 欄目:編程語言

今天小編給大家分享一下v-for和v-if的優先級哪個更高的相關知識點,內容詳細,邏輯清晰,相信大部分人都還太了解這方面的知識,所以分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后有所收獲,下面我們一起來了解一下吧。

結論

1、本身并不建議將v-for和v-if同時使用的。

2、vue2里面v-for比v-if的優先級更高。因為vue2在模板編譯的時候會先處理v-for再處理v-if,所以生成的渲染函數會先執行循環,然后在循環里面再執行條件判斷。

3、這樣做帶來的問題就是

對于場景1:<li v-for="user in users" v-if="user.show">

每次重新渲染的時候,都要重新遍歷整個列表,其實我們只需要列表的一部分,這樣做浪費性能。推薦的做法是,通過計算屬性先過濾出我們需要的部分,再去渲染,更高效。

對于場景2: <li v-for="user in users" v-if="globalShow">

globalShow這個判斷其實如果是false,循環并不需要執行,但是現在跟v-if一起用,不管globalShow是否是true都要執行循環,完全是浪費。推薦的做法是將v-if上移到ul容器。

4、需要注意的是,vue3的breaking change,在vue3中v-if的優先級比v-for高,所以如果同時使用的話,對于場景1,這個時候user還沒有,v-if="user.show"就會報錯

5、一般我們如果有用eslint,也會給我們報錯,對應的規則是:vue/no-use-v-if-with-v-for

實際例子

例如:以下的模板,將會生成下面的渲染函數

<ul>
    <li v-for="user in users" v-if="user.isActive" :key="user.id">
        {{ user.name }}
    </li>
</ul>

生成的渲染函數如下

with(this) {
    return _c('ul', _l((users), function (user) {
        return (user.isActive) ? _c('li', user.name) : _e()
    }), 0)
}

從上面生成的渲染函數可以看出,會先執行_l遍歷user,在里面進行條件判斷

源碼

處理v-if和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)

根據ast生成代碼,假如是上面的模板,生成的ast簡化后如下

// 可以看出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()
});

以上就是“v-for和v-if的優先級哪個更高”這篇文章的所有內容,感謝各位的閱讀!相信大家閱讀完這篇文章都有很大的收獲,小編每天都會為大家更新不同的知識,如果還想學習更多的知識,請關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

陈巴尔虎旗| 南岸区| 阳信县| 重庆市| 南城县| 江都市| 通州区| 西充县| 上犹县| 西盟| 南召县| 桐乡市| 黔南| 三门县| 大姚县| 福建省| 县级市| 固安县| 莱芜市| 巴南区| 岐山县| 南涧| 井陉县| 莒南县| 仙桃市| 江门市| 天峻县| 苍溪县| 茂名市| 建宁县| 朝阳市| 宁河县| 从江县| 全州县| 天台县| 板桥市| 榆中县| 元阳县| 徐州市| 伊宁市| 东明县|