详解为什么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 +WebSocket + WaveSurferJS 实现H5聊天对话交互的实例
Nov 18 Vue.js
vue 获取到数据但却渲染不到页面上的解决方法
Nov 19 Vue.js
使用vue编写h5公众号跳转小程序的实现代码
Nov 27 Vue.js
Vue router传递参数并解决刷新页面参数丢失问题
Dec 02 Vue.js
如何正确解决VuePress本地访问出现资源报错404的问题
Dec 03 Vue.js
Vue 实现一个简单的鼠标拖拽滚动效果插件
Dec 10 Vue.js
Vue仿Bibibili首页的问题
Jan 21 Vue.js
Vue 3自定义指令开发的相关总结
Jan 29 Vue.js
如何使用RoughViz可视化Vue.js中的草绘图表
Jan 30 Vue.js
详解Vue3.0 + TypeScript + Vite初体验
Feb 22 Vue.js
vue实现Toast组件轻提示
Apr 10 Vue.js
Vue3实现简易音乐播放器组件
Aug 14 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
漫荒推荐:画风超赞的国风漫画推荐 超长假期不无聊
2020/03/08 国漫
搜索和替换文件或目录的一个好类--很实用
2006/10/09 PHP
PHP 5.3新特性命名空间规则解析及高级功能
2010/03/11 PHP
php array_search() 函数使用
2010/04/13 PHP
php和javascript之间变量的传递实现代码
2012/12/19 PHP
php中运用http调用的GET和POST方法示例
2014/09/29 PHP
一键生成各种尺寸Icon的php脚本(实例)
2017/02/08 PHP
经验几则 推荐
2006/09/05 Javascript
JavaScript Tips 使用DocumentFragment加快DOM渲染速度
2010/06/28 Javascript
jquery删除提示框弹出是否删除对话框
2014/01/07 Javascript
解决json日期格式问题的3种方法
2014/02/02 Javascript
jQuery Masonry瀑布流插件使用详解
2014/11/17 Javascript
angularjs学习笔记之双向数据绑定
2015/09/26 Javascript
jquery form表单获取内容以及绑定数据
2016/02/24 Javascript
解析预加载显示图片艺术
2016/12/05 Javascript
使用Promise链式调用解决多个异步回调的问题
2017/01/15 Javascript
Vue 菜单栏点击切换单个class(高亮)的方法
2018/08/22 Javascript
深入了解Hybrid App技术的相关知识
2019/07/17 Javascript
vue实现中部导航栏布局功能
2019/07/30 Javascript
[01:29:17]RNG vs Liquid 2019国际邀请赛淘汰赛 败者组 BO3 第二场 8.23
2019/09/05 DOTA
python冒泡排序简单实现方法
2015/07/09 Python
Python 专题三 字符串的基础知识
2017/03/19 Python
Python3用tkinter和PIL实现看图工具
2018/06/21 Python
Python rstrip()方法实例详解
2018/11/11 Python
pytorch GAN伪造手写体mnist数据集方式
2020/01/10 Python
Python Map 函数的使用
2020/08/28 Python
python爬虫爬取某网站视频的示例代码
2021/02/20 Python
html5实现多文件的上传示例代码
2014/02/13 HTML / CSS
美国折扣网站:jClub
2017/08/07 全球购物
资产评估专业大学生求职信
2013/09/29 职场文书
养殖人员的创业计划书范文
2013/12/26 职场文书
幼儿园门卫制度
2014/01/29 职场文书
优秀信贷员先进事迹
2014/01/31 职场文书
高中微机老师自我鉴定
2014/02/16 职场文书
学习经验交流会总结
2015/11/02 职场文书
详解Redis集群搭建的三种方式
2021/05/31 Redis