IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> Vue面试集合 -> 正文阅读

[JavaScript知识库]Vue面试集合

1. v-if和v-for哪个优先级更高?如果同时出现,怎么优化得到更好的性能

源码中找答案:complier/codegen/index.js

测试文件

测试文件

<!DOCTYPE html>
<htm>
  <head>
    <titl>Vue事件处理</titl>
  </head>

  <body>
    <div id="demo">
      <h1>v-for 和 v-if谁的优先级高? 应该如何正确使用避免性能问题?</h1>
      <p v-for="child in children" v-if="isFolder">{{child.title}}</p>
	

      <!-- <template v-if="isFolder">
        <p v-for="child in children">{{child.title}}</p>
      </template> -->
    </div>
    <script src="assets/vue.js"></script>
    <script>
      const app = new Vue({
        el:'#demo',
        data() {
          return {
            children:[
              {title:'foo'},
              {title:'bar'},
            ]
          }
        },
        computed:{
          isFolder() {
            return this.children && this.children.length > 0
          }
        },
      });
      console.log(app.$options.render);
    </script>
  </body>
</htm>

结果分析

两者同级时,渲染函数如下

  (function anonymous(
      ) {
      with(this){return _c('div',{attrs:{"id":"demo"}},
      [_c('h1',[_v("v-for 和 v-if谁的优先级高? 应该如何正确使用避免性能问题?")]),
      _v(" "),
      _l((children),function(child){return (isFolder)?_c('p',[_v(_s(child.title))]):_e()})],2)}
      })

先执行循环遍历_l,再进行判断

两者不同级时

(function anonymous(
        ) {
          with(this){return _c('div',{attrs:{"id":"demo"}},
          [_c('h1',[_v("v-for 和 v-if谁的优先级高? 应该如何正确使用避免性能问题?")]),_v(" "),
          (isFolder)?_l((children),function(child){return _c('p',[_v(_s(child.title))])}):_e()],2)}
      }) 

先判断在执行循环_l

结论

  1. v-for的优先级高于v-if, 测试代码如上,需要设置同级和不同级的场景,且源码中在complier/codegen/index.js下有优先级定义
    在这里插入图片描述

  2. 如果同时出现,每次渲染都会先执行循环再判断条件,无论如何循环都不可避免,浪费了性能

  3. 要避免出现这种情况,则在外层嵌套template,在这一层进行v-if判断,然后在内部进行v-for循环。最终提供给模板的就是需要渲染的

2. Vue组件的data为什么必须是个函数而Vue的根实例没有限制?

源码中找答案
函数每次执行都会返回全新data对象实例
在这里插入图片描述

测试代码

<!DOCTYPE html>
<htm>
  <head>
    <titl>Vue事件处理</titl>
  </head>

  <body>
    <div id="demo">
      <h1>Vue组件data为什么必须是个函数?</h1>
      <comp></comp>
      <comp></comp>
      <p>{{counter}}</p>
    </div>
    <script src="assets/vue.js"></script>
    <script>
      Vue.component('comp', {
        template: '<div @click="counter++">{{counter}}</div>',
			 data: {counter: 0}
			 //data(){return {counter:0}}

      })
      const app = new Vue({
        el:'#demo',
        //data:{cuonter:0}
      });
      console.log(app.$options.render);
    </script>
  </body>
</htm>

在这里插入图片描述> 程序无法通过vue检测

结论

Vue组件可能存在多个实例,如果使用对象形式定义data,则会导致它们共用一个data对象,那么状态更新会影响所有组件,这是不合理的。采用函数形式定义,在initData时会将其作为工厂函数返回全新的data对象,有效规避多实例之间状态污染问题。
而在Vue根实例创建过程中则不存在限制,也是因为根实例只有一个,不需要担心这种情况

源码中会检测data的形式,决定具体的执行方式
合并选项时,会创建实例,只有根实例有实例,可以有效躲过data选项校验;普通选项不存在实例,无法躲过校验的if逻辑

在这里插入图片描述

3. vue中key的作用和工作原理

源码中找答案:

src\core\vdom\patch.js - updateChildren()

测试代码

<!DOCTYPE html>
<html lang="en">
<meta charset="utf-8">
<head>
  <titl>Vue事件处理</titl>
</head>

<body>
<div id="demo">
  <p v-for="item in items">{{item}}</p>
</div>
<script src="../../dist/vue.js"></script>
<script>

	const app = new Vue({
		el: '#demo',
		data: {items: ['a', 'b', 'c', 'd', 'e']},
		mounted() {
			setTimeout(() => {
				//在c的前面插入f
				this.items.splice(2, 0, 'f')
			}, 2000);
		}
	});
</script>
</body>
</html>

图解

在这里插入图片描述使用key

//首次循环patch A
A B C D E
A B F C D E
//第二次循环patch B
B C D E
B F C D E

//第三次patch E
C D E
F C D E

//第四次循环patch D
C D 
F C D

//第5次循环patch C
C
F C

//oldch全部处理结束,newch中剩下的F,创建F并插入到C前面

调试分析过程

在这里插入图片描述没有key时,值为undefiend,则两个标签相同,但值不同,vue源码会认为相同
在这里插入图片描述

结论

1、key的作用主要是为了高效的更新虚拟DOM, 其原理是vue在patch过程中通过key可以精准判断两个节点是否是同一个,从而避免频繁更新不同的元素,使得整个patch过程更加高效,减少DOM操作量,提高性能。

2、另外,若不设置key还可能在列表更新时一份一些隐藏bug
3、vue中在使用相同标签名元素的过度切换时,也会使用到key属性,其目的也是为了让vue可以区分它们,否则vue只会替换其内部属性而不会触发过渡效果

  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2021-08-22 13:28:04  更:2021-08-22 13:29:18 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 12:54:33-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码