详解为什么Vue中的v-if和v-for不建议一起用


Posted in Vue.js onJanuary 13, 2021

本文主要介绍了为什么v-if和v-for不建议一起用?分享给大家,具体如下:

详解为什么Vue中的v-if和v-for不建议一起用

一、作用

v-if 指令用于条件性地渲染一块内容。这块内容只会在指令的表达式返回 true值的时候被渲染

v-for 指令基于一个数组来渲染一个列表。v-for 指令需要使用 item in items 形式的特殊语法,其中 items 是源数据数组或者对象,而 item 则是被迭代的数组元素的别名

在 v-for 的时候,建议设置key值,并且保证每个key值是独一无二的,这便于diff算法进行优化

两者在用法上

<Modal v-if="isShow" />
 
<li v-for="item in items" :key="item.id">
  {{ item.label }}
</li>

二、优先级

v-if与v-for都是vue模板系统中的指令

在vue模板编译的时候,会将指令系统转化成可执行的render函数

示例

编写一个p标签,同时使用v-if与 v-for

<div id="app">
  <p v-if="isShow" v-for="item in items">
    {{ item.title }}
  </p>
</div>

创建vue实例,存放isShow与items数据

const app = new Vue({
 el: "#app",
 data() {
  return {
   items: [
    { title: "foo" },
    { title: "baz" }]
  }
 },
 computed: {
  isShow() {
   return this.items && this.items.length > 0
  }
 }
})

模板指令的代码都会生成在render函数中,通过app.$options.render就能得到渲染函数

ƒ anonymous() {
 with (this) { return 
  _c('div', { attrs: { "id": "app" } }, 
  _l((items), function (item) 
  { return (isShow) ? _c('p', [_v("\n" + _s(item.title) + "\n")]) : _e() }), 0) }
}

_l是vue的列表渲染函数,函数内部都会进行一次if判断

初步得到结论:v-for优先级是比v-if高

再将v-for与v-if置于不同标签

<div id="app">
  <template v-if="isShow">
    <p v-for="item in items">{{item.title}}</p>
  </template>
</div>

再输出下render函数

ƒ anonymous() {
 with(this){return 
  _c('div',{attrs:{"id":"app"}},
  [(isShow)?[_v("\n"),
  _l((items),function(item){return _c('p',[_v(_s(item.title))])})]:_e()],2)}
}

这时候我们可以看到,v-for与v-if作用在不同标签时候,是先进行判断,再进行列表的渲染

我们再在查看下vue源码

源码位置:\vue-dev\src\compiler\codegen\index.js

export function genElement (el: ASTElement, state: CodegenState): string {
 if (el.parent) {
  el.pre = el.pre || el.parent.pre
 }
 if (el.staticRoot && !el.staticProcessed) {
  return genStatic(el, state)
 } else if (el.once && !el.onceProcessed) {
  return genOnce(el, state)
 } 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 {
  // component or element
  ...
}

在进行if判断的时候,v-for是比v-if先进行判断

最终结论:v-for优先级比v-if高

三、注意事项

永远不要把 v-if 和 v-for 同时用在同一个元素上,带来性能方面的浪费(每次渲染都会先循环再进行条件判断)

如果避免出现这种情况,则在外层嵌套template(页面渲染不生成dom节点),在这一层进行v-if判断,然后在内部进行v-for循环

<template v-if="isShow">
  <p v-for="item in items">
</template>

如果条件出现在循环内部,可通过计算属性computed提前过滤掉那些不需要显示的项

computed: {
  items: function() {
   return this.list.filter(function (item) {
    return item.isShow
   })
  }
}

参考文献

https://vue3js.cn/docs/zh\

到此这篇关于详解为什么Vue中的v-if和v-for不建议一起用的文章就介绍到这了,更多相关v-if和v-for不建议一起用内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Vue.js 相关文章推荐
实用的 vue tags 创建缓存导航的过程实现
Dec 03 Vue.js
vue表单验证之禁止input输入框输入空格
Dec 03 Vue.js
Vue实现手机号、验证码登录(60s禁用倒计时)
Dec 19 Vue.js
vue中封装axios并实现api接口的统一管理
Dec 25 Vue.js
详解vue之自行实现派发与广播(dispatch与broadcast)
Jan 19 Vue.js
Vue 集成 PDF.js 实现 PDF 预览和添加水印的步骤
Jan 22 Vue.js
vue登录页实现使用cookie记住7天密码功能的方法
Feb 18 Vue.js
vue常用高阶函数及综合实例
Feb 25 Vue.js
vite+vue3.0+ts+element-plus快速搭建项目的实现
Jun 24 Vue.js
Vue.js中v-for指令的用法介绍
Mar 13 Vue.js
Vue2项目中对百度地图的封装使用详解
Jun 16 Vue.js
vue自定义组件实现双向绑定
Jan 13 #Vue.js
Vue页面渲染中key的应用实例教程
Jan 12 #Vue.js
Vue项目中使用mock.js的完整步骤
Jan 12 #Vue.js
vue 页面跳转的实现方式
Jan 12 #Vue.js
Vue过滤器,生命周期函数和vue-resource简单介绍
Jan 12 #Vue.js
详解template标签用法(含vue中的用法总结)
Jan 12 #Vue.js
Vue中ref和$refs的介绍以及使用方法示例
Jan 11 #Vue.js
You might like
php实现查看邮件是否已被阅读的方法
2013/12/03 PHP
PHP登录验证码的实现与使用方法
2016/07/07 PHP
php  单例模式详细介绍及实现源码
2016/11/05 PHP
php读取qqwry.dat ip地址定位文件的类实例代码
2016/11/15 PHP
PHP 信号管理知识整理汇总
2017/02/19 PHP
javascript原型链继承用法实例分析
2015/01/28 Javascript
基于jQuery实现动态数字展示效果
2015/08/12 Javascript
Bootstrap入门书籍之(五)导航条、分页导航
2016/02/17 Javascript
Web开发必知Javascript技巧大全
2016/02/23 Javascript
详解AngularJS过滤器的使用
2016/03/11 Javascript
jQuery图片轮播插件——前端开发必看
2016/05/31 Javascript
js实现小窗口拖拽效果
2016/12/03 Javascript
node.js基于fs模块对系统文件及目录进行读写操作的方法详解
2017/11/10 Javascript
Vue.js 踩坑记之双向绑定
2018/05/03 Javascript
ES6知识点整理之函数对象参数默认值及其解构应用示例
2019/04/17 Javascript
Node.js实现用户评论社区功能(体验前后端开发的乐趣)
2019/05/09 Javascript
python实现批量改文件名称的方法
2015/05/25 Python
python web框架学习笔记
2016/05/03 Python
Python基础教程之浅拷贝和深拷贝实例详解
2017/07/15 Python
对python append 与浅拷贝的实例讲解
2018/05/04 Python
python 动态生成变量名以及动态获取变量的变量名方法
2019/01/20 Python
Django使用unittest模块进行单元测试过程解析
2019/08/02 Python
Python自动生成代码 使用tkinter图形化操作并生成代码框架
2019/09/18 Python
手把手教你安装Windows版本的Tensorflow
2020/03/26 Python
探讨HTML5移动开发的几大特性(必看)
2015/12/30 HTML / CSS
雅诗兰黛旗下走天然植物路线的彩妆品牌:Prescriptives
2016/08/14 全球购物
Ruby中的保护方法和私有方法与一般面向对象程序设计语言的一样吗
2013/05/01 面试题
师范毕业生个人求职信
2013/12/09 职场文书
建筑工程专业学生的自我评价
2013/12/25 职场文书
长城英文导游词
2015/01/30 职场文书
求职简历自我评价怎么写
2015/03/10 职场文书
三国演义读书笔记
2015/06/25 职场文书
小学三年级数学教学反思
2016/02/16 职场文书
合同范本之电脑出租
2019/08/13 职场文书
《堡垒之夜》联动《刺客信条》 4月7日正式上线
2022/04/06 其他游戏
Win11运行cmd提示“请求的操作需要提升”的两种解决方法
2022/07/07 数码科技