목차
结论
实际例子
源码
결론
실제 예
소스 코드
웹 프론트엔드 View.js 우선순위 비교: v-for 또는 v-if 중 어느 것이 더 높습니까?

우선순위 비교: v-for 또는 v-if 중 어느 것이 더 높습니까?

Aug 29, 2022 pm 07:52 PM
vue v-if v-for

v-for와 v-if 중 어느 것이 더 높은 우선순위를 갖나요? 다음 글에서는 실제 예제와 소스코드를 통해 v-forv-if의 우선순위를 설명하겠습니다.
v-forv-if的优先级,相信你看完后会茅塞顿开的。

우선순위 비교: v-for 또는 v-if 중 어느 것이 더 높습니까?

结论

1、本身并不建议将v-for和v-if同时使用的。(学习视频分享:vue视频教程

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)}` +
'})'
로그인 후 복사

最终会生成类似如下的代码返回出去

우선순위 비교: v-for 또는 v-if 중 어느 것이 더 높습니까?

결론

1. v-for와 v-if를 동시에 사용하는 것은 권장되지 않습니다. (학습 영상 공유: vue 영상 튜토리얼)2. vue2에서는 v-for가 v-if보다 우선순위가 높습니다. vue2는 템플릿을 컴파일할 때 v-for를 먼저 처리한 다음 v-if를 처리하기 때문에 생성된 렌더링 함수는 먼저 루프를 실행한 다음 루프 내에서 조건부 판단을 실행합니다. 🎜3 이렇게 하면 발생하는 문제는 🎜🎜시나리오 1의 경우: <li v-for="user in users" v-if="user.show">🎜🎜Every 다시 렌더링할 때마다 전체 목록을 다시 순회해야 하기 때문에 실제로는 목록의 일부만 필요하므로 성능이 낭비됩니다. 권장되는 접근 방식은 계산된 속성을 통해 필요한 부품을 필터링한 다음 렌더링하는 것인데, 이는 더 효율적입니다. 🎜🎜시나리오 2의 경우: <li v-for="user in users" v-if="globalShow">🎜🎜실제로 globalShow의 판단이 거짓인 경우 루프는 실행할 필요가 없습니다. 그러나 이제 v-if와 함께 사용하면 globalShow가 true인지 여부에 관계없이 루프를 실행해야 하는데 이는 완전한 낭비입니다. 권장되는 접근 방식은 v-if를 ul 컨테이너로 이동하는 것입니다. 🎜🎜4 vue3의 획기적인 변경의 경우 v-if가 vue3의 v-for보다 우선순위가 높으므로 동시에 사용하는 경우 시나리오 1의 경우 사용자는 아직 사용되지 않았습니다. 이번에는 v-if=" user.show"가 오류를 보고합니다🎜🎜5. 일반적으로 eslint를 사용하면 해당 규칙도 vue/no-use-v-if입니다. -with-v-for🎜

실제 예

🎜예: 다음 템플릿은 다음 렌더링 함수를 생성합니다🎜
_l((users), function(user, index) {
    // 如果有v-if 前面就会有个条件判断,如user.isActive
    return (user.isActive) ? _c('li', user.name) : _e()
});
로그인 후 복사
🎜생성된 렌더링 함수는 다음과 같습니다🎜rrreee 🎜위에서 생성된 렌더링 함수에서 볼 수 있듯이 _luser를 순회하고 거기에서 조건부 판단을 수행하는 것이 먼저 실행됩니다🎜

소스 코드

🎜v-if 및 v-for 처리 소스 코드🎜🎜src/compiler/index.js🎜rrreee🎜는 ast를 기반으로 코드를 생성합니다. 위 템플릿에서 생성된 ast는 다음과 같이 단순화됩니다.🎜rrreee🎜compiler/codegen/index.js🎜rrreee🎜결국 다음과 유사한 코드를 생성하여 반환합니다🎜rrreee 🎜 (학습 영상 공유: 🎜웹 프론트엔드 개발🎜, 🎜기본 프로그래밍 영상🎜)🎜

위 내용은 우선순위 비교: v-for 또는 v-if 중 어느 것이 더 높습니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.

핫 AI 도구

Undresser.AI Undress

Undresser.AI Undress

사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover

AI Clothes Remover

사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool

Undress AI Tool

무료로 이미지를 벗다

Clothoff.io

Clothoff.io

AI 옷 제거제

Video Face Swap

Video Face Swap

완전히 무료인 AI 얼굴 교환 도구를 사용하여 모든 비디오의 얼굴을 쉽게 바꾸세요!

뜨거운 도구

메모장++7.3.1

메모장++7.3.1

사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전

SublimeText3 중국어 버전

중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기

스튜디오 13.0.1 보내기

강력한 PHP 통합 개발 환경

드림위버 CS6

드림위버 CS6

시각적 웹 개발 도구

SublimeText3 Mac 버전

SublimeText3 Mac 버전

신 수준의 코드 편집 소프트웨어(SublimeText3)

Vue에서 부트 스트랩을 사용하는 방법 Vue에서 부트 스트랩을 사용하는 방법 Apr 07, 2025 pm 11:33 PM

vue.js에서 bootstrap 사용은 5 단계로 나뉩니다 : Bootstrap 설치. main.js.의 부트 스트랩 가져 오기 부트 스트랩 구성 요소를 템플릿에서 직접 사용하십시오. 선택 사항 : 사용자 정의 스타일. 선택 사항 : 플러그인을 사용하십시오.

Vue 용 버튼에 기능을 추가하는 방법 Vue 용 버튼에 기능을 추가하는 방법 Apr 08, 2025 am 08:51 AM

HTML 템플릿의 버튼을 메소드에 바인딩하여 VUE 버튼에 함수를 추가 할 수 있습니다. 메소드를 정의하고 VUE 인스턴스에서 기능 로직을 작성하십시오.

Vue에서 시계를 사용하는 방법 Vue에서 시계를 사용하는 방법 Apr 07, 2025 pm 11:36 PM

vue.js의 시계 옵션을 사용하면 개발자가 특정 데이터의 변경 사항을들을 수 있습니다. 데이터가 변경되면 콜백 기능을 트리거하여 업데이트보기 또는 기타 작업을 수행합니다. 구성 옵션에는 즉시 콜백을 실행할지 여부와 DEEP를 지정하는 즉시 포함되며, 이는 객체 또는 어레이에 대한 변경 사항을 재귀 적으로 듣는 지 여부를 지정합니다.

Vue 다중 페이지 개발은 무엇을 의미합니까? Vue 다중 페이지 개발은 무엇을 의미합니까? Apr 07, 2025 pm 11:57 PM

VUE 멀티 페이지 개발은 vue.js 프레임 워크를 사용하여 응용 프로그램을 구축하는 방법입니다. 여기서 응용 프로그램은 별도의 페이지로 나뉩니다. 코드 유지 보수 : 응용 프로그램을 여러 페이지로 분할하면 코드를보다 쉽게 ​​관리하고 유지 관리 할 수 ​​있습니다. 모듈 식 : 각 페이지는 쉬운 재사용 및 교체를 위해 별도의 모듈로 사용할 수 있습니다. 간단한 라우팅 : 페이지 간의 탐색은 간단한 라우팅 구성을 통해 관리 할 수 ​​있습니다. SEO 최적화 : 각 페이지에는 자체 URL이있어 SEO가 도움이됩니다.

Vue가 이전 페이지로 돌아 오는 방법 Vue가 이전 페이지로 돌아 오는 방법 Apr 07, 2025 pm 11:30 PM

vue.js는 이전 페이지로 돌아갈 수있는 네 가지 방법이 있습니다. $ router.go (-1) $ router.back () 사용 & lt; router-link to = & quot;/quot; Component Window.history.back () 및 메소드 선택은 장면에 따라 다릅니다.

React vs. Vue : Netflix는 어떤 프레임 워크를 사용합니까? React vs. Vue : Netflix는 어떤 프레임 워크를 사용합니까? Apr 14, 2025 am 12:19 AM

NetflixusesAcustomFrameworkCalled "Gibbon"BuiltonReact, NotreactorVuedirectly.1) TeamExperience : 2) ProjectComplexity : vueforsimplerProjects, 3) CustomizationNeeds : reactoffersmoreflex.4)

Vue Traversal 사용 방법 Vue Traversal 사용 방법 Apr 07, 2025 pm 11:48 PM

vue.js가 트래버스 어레이 및 객체에 대한 세 가지 일반적인 방법이 있습니다. V- 결합 지시문은 V-FOR와 함께 사용하여 각 요소의 속성 값을 동적으로 설정할 수 있습니다. .MAP 메소드는 배열 요소를 새 배열로 변환 할 수 있습니다.

Vue의 div로 점프하는 방법 Vue의 div로 점프하는 방법 Apr 08, 2025 am 09:18 AM

VUE에서 DIV 요소를 점프하는 두 가지 방법이 있습니다. VUE 라우터를 사용하고 라우터 링크 구성 요소를 추가하십시오. @Click 이벤트 리스너를 추가하고 이것을 호출하십시오. $ router.push () 메소드를 점프하십시오.

See all articles