当前位置:   article > 正文

vue高频面试题_vue中高级面试题

vue中高级面试题

1.为什么data是个函数并且返回一个对象呢?

data之所以只一个函数,是因为一个组件可能会多处调用,而每一次调用就会执行data函数并返回新的数据对象,这样,可以避免多处调用之间的数据污染。

2.组件之间的传值方式有哪些?

  • 父组件传值给子组件,子组件使用props进行接收
  • 子组件传值给父组件,子组件使用$emit+事件对父组件进行传值
  • 组件中可以使用$ parent和$children获取到父组件实例和子组件实例,进而获取数据
  • 使用$ attrs和$ listeners,在对一些组件进行二次封装时可以方便传值,例如A->B->C
    • 使用provide和inject,官方建议我们不要用这个,我在看ElementUI源码时发现大量使用
  • 使用$refs获取组件实例,进而获取数据
  • 使用Vuex进行状态管理
  • 使用eventBus进行跨组件触发事件,进而传递数据
  • 使用浏览器本地缓存,例如localStorage

vue2中 a t t r s 不包含了父作用域中作为 p r o p 被识别 ( 且获取 ) 的 a t t r i b u t e 绑定, attrs 不 包含了父作用域中作为 prop 被识别 (且获取) 的 attribute 绑定, attrs不包含了父作用域中作为prop被识别(且获取)attribute绑定,listeners包含了父作用域中所有不为.native 的v-on
vue3 a t t r s 对象包含了除组件所声明的 p r o p s 和 e m i t s 之外的所有其他 a t t r i b u t e ,例如 c l a s s , s t y l e , v − o n 监听器等等。 attrs 对象包含了除组件所声明的 props 和 emits 之外的所有其他 attribute,例如 class,style,v-on 监听器等等。 attrs对象包含了除组件所声明的propsemits之外的所有其他attribute,例如classstylevon监听器等等。listeners合并到里面去了

3.路由有哪些模式呢?又有什么不同呢?

  • hash模式:通过#号后面的内容的更改,触发hashchange事件,实现路由切换
  • history模式:通过pushState和replaceState切换url,触发popstate事件,实现路由切换,上线需nginx配置

4.不需要响应式的数据应该怎么处理?

在我们的Vue开发中,会有一些数据,从始至终都未曾改变过,这种死数据,既然不改变,那也就不需要对他做响应式处理了,不然只会做一些无用功消耗性能,比如一些写死的下拉框,写死的表格数据,这些数据量大的死数据,如果都进行响应式处理,那会消耗大量性能。

// 方法一:将数据定义在data之外
data () {
    this.list1 = { xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx }
    this.list2 = { xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx }
    this.list3 = { xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx }
    this.list4 = { xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx }
    this.list5 = { xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx }
    return {}
 }
    
// 方法二:Object.freeze()
data () {
    return {
        list1: Object.freeze({xxxxxxxxxxxxxxxxxxxxxxxx}),
        list2: Object.freeze({xxxxxxxxxxxxxxxxxxxxxxxx}),
        list3: Object.freeze({xxxxxxxxxxxxxxxxxxxxxxxx}),
        list4: Object.freeze({xxxxxxxxxxxxxxxxxxxxxxxx}),
        list5: Object.freeze({xxxxxxxxxxxxxxxxxxxxxxxx}),
    }
 }

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

4.父子组件生命周期顺序

父beforeCreate -> 父created -> 父beforeMount -> 子beforeCreate -> 子created -> 子beforeMount -> 子mounted -> 父mounted

5.为什么不建议用index做key,为什么不建议用随机数做key?

举个例子:

<div v-for=(item, index) in list :key=index>{{item.name}}</div>

list: [
    { name: '小明', id: '123' },
    { name: '小红', id: '124' },
    { name: '小花', id: '125' }
]

渲染为
<div key=0>小明</div>
<div key=1>小红</div>
<div key=2>小花</div>

现在我执行 list.unshift({ name: '小林', id: '122' })

渲染为
<div key=0>小林</div>
<div key=1>小明</div>
<div key=2>小红</div>
<div key=3>小花</div>


新旧对比

<div key=0>小明</div>  <div key=0>小林</div>
<div key=1>小红</div>  <div key=1>小明</div>
<div key=2>小花</div>  <div key=2>小红</div>
                         <div key=3>小花</div>

可以看出,如果用index做key的话,其实是更新了原有的三项,并新增了小花,虽然达到了渲染目的,但是损耗性能

现在我们使用id来做key,渲染为

<div key=123>小明</div>
<div key=124>小红</div>
<div key=125>小花</div>

现在我执行 list.unshift({ name: '小林', id: '122' }),渲染为

<div key=122>小林</div>
<div key=123>小明</div>
<div key=124>小红</div>
<div key=125>小花</div>

新旧对比

                           <div key=122>小林</div>
<div key=123>小明</div>  <div key=123>小明</div>
<div key=124>小红</div>  <div key=124>小红</div>
<div key=125>小花</div>  <div key=125>小花</div>

可以看出,原有的三项都不变,只是新增了小林这个人,这才是最理想的结果
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52

用index和用随机数都是同理,随机数每次都在变,做不到专一性,
因为假设我们给数组前插入一个新元素,它的下标是0,那么和原来的第一个元素重复了,整个数组的key都发生了改变,这样就跟没有key的情况一样了

如果不存在对数据的逆序添加,逆序删除等破坏顺序的操作,仅用于渲染列表用于展示, 使用index作为key是没有问题的。

6.审查元素时发现data-v-xxxxx,这是啥?

在这里插入图片描述

这是在标记vue文件中css时使用scoped标记产生的,因为要保证各文件中的css不相互影响,给每个component都做了唯一的标记,所以每引入一个component就会出现一个新的’data-v-xxx’标记

7.vue的hook的使用

1.使用定时器的方式

export default{
  data(){
    timer:null  
  },
  mounted(){
      this.timer = setInterval(()=>{
      //具体执行内容
      console.log('1');
    },1000);
  }
  beforeDestory(){
    clearInterval(this.timer);
    this.timer = null;
  }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

上面做法不好的地方在于:得全局多定义一个timer变量,可以使用hook这么做:

export default{
  methods:{
    fn(){
      const timer = setInterval(()=>{
        //具体执行代码
        console.log('1');
      },1000);
      this.$once('hook:beforeDestroy',()=>{
        clearInterval(timer);
        timer = null;
      })
    }
  }
}
//$once是一个函数,可以为Vue组件实例绑定一个自定义事件,但该事件只能被触发一次,触发之后随即被移除。
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

2.如果子组件需要在mounted时触发父组件的某一个函数,平时都会这么写:

//父组件
<rl-child @childMounted=childMountedHandle
/>
method () {
  childMountedHandle() {
  // do something...
  }
},

// 子组件
mounted () {
  this.$emit('childMounted')
},
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

使用hook的话可以更方便:

//父组件
<rl-child @hook:mounted=childMountedHandle
/>
method () {
  childMountedHandle() {
  // do something...
  }
},

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

8.动态指令和参数使用过吗?

<template>
    ...
    <aButton @[someEvent]=handleSomeEvent() :[someProps]=1000 />...
</template>
<script>
  ...
  data(){
    return{
      ...
      someEvent: someCondition ? click : dbclick,
      someProps: someCondition ? num : price
    }
  },
  methods: {
    handleSomeEvent(){
      // handle some event
    }
  }  
</script>

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

9、写 React / Vue 项目时为什么要在列表组件中写 key,其作用是什么?

有key并不一定会提升diff速度,1、当遍历模板简单 如 <div v-for="i in dataList">{{ i }}</div> 会导致虚拟新旧节点对比更快,节点也会复用。

而这种复用是就地复用,这就是vue文档所说的默认模式,没有key的情况下可以对节点就地复用,只修改文本,提高性能。

因为带唯一key时每次更新都不能找到可复用的节点,不但要销毁和创建vnode,在DOM里添加移除节点对性能的影响更大。当然这是相对于简单模板的情况下

既然如此,为什么还要建议带key呢?因为这种模式只适用于渲染简单的无状态组件。对于大多数场景来说,列表组件都有自己的状态。

但是key的作用是什么?

key是给每一个vnode的唯一id,可以依靠key,更准确, 更快的拿到oldVnode中对应的vnode节点。

  1. 更准确
    因为带key就不是就地复用了,在sameNode函数 a.key === b.key对比中可以避免就地复用的情况。所以会更加准确。
  2. 更快
    利用key的唯一性生成map对象来获取对应节点,比遍历方式更快。(这个观点,就是我最初的那个观点。从这个角度看,map会比遍历更快。)
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/IT小白/article/detail/132531
推荐阅读
相关标签
  

闽ICP备14008679号