• 【前端vue面试】vue2


    computed和watch

    computed 有缓存,基于响应式依赖数据(基于data中声明过或者父组件传递的props中的数据)发生改变,才会重新进行计算
    数据变,直接会触发相应的操作
    watch监听引用类型,需要添加deep:true深度监听,拿不到oldVal(旧值),因为新值和老值指针相同。

    v-show和v-if

    1. v-show 和v-if 都是做条件隐藏和显示用
    2. v-show 是通过css操作dom。在初始化Dom渲染的时候会将显示的内容跟隐藏的内容,同时渲染,只是根据条件设置css为 display: none
    3. v-if在初始化Dom渲染的时候,根据条件显示需要展示的内容,并销毁隐藏的内容。每次条件切换时,都需要销毁隐藏的内容
    4. v-if 频繁切换渲染消耗高,v-show 初始化渲染消耗高。
      优化建议:频繁切换节点 使用v-show

    key 的重要性

    key不能不写或乱写(如 random、index 或不是唯一索引键)
    key涉及到vu的diff算法,在新旧nodes对比识别VNodes。它的作用主要是为高效的更新虚拟DOM。vue会基于key的变化重新排列元素顺序,并且会移除可以不存在的元素。有相同父元素必须有独特的key。重复的key会造成渲染错误。

    v-for 和 v-if 不能一起使用!

    v-for 具有比 v-if 更高的优先级,这意味着 v-if 将分别重复运行于每个 v-for 循环中,不利于性能优化
    建议:

    1. 使用computed
    2. 数组情况下: v-for=“(item,index) in Array.filter(v => v.value)”
    3. v-for外层或里层再套一层用v-if

    @click的event

    1. 不需要传参数的 可以直接在methods方法的对应事件函数中直接获取获取event
    //template
    @click="fun1" 
    //methods
    fun1(event){
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    1. 需要传参数的,需要把event参数带过去,使用$event
    //template
    @click="fun2(2,$event)" 
    //methods
    fun2(val,event){
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    修饰符

    事件修饰符

    • stop: 阻止事件冒泡
    • prevent: 阻止默认事件,如超链接标签的重定向
    • capture: 网页是默认按照冒泡方式去触发函数的,但是当我们使用.capture修饰符时,网页就会按照捕获的方式触发函数,也就是从外向内执行,但是这个时候一定要注意,.capture修饰符一定要写在外层才能生效

    表单项修饰符

    • trim: 截掉前后空格
    • lazy: 类似防抖,输入结束后才会变化,输入的过程中不会变化
    • number: 转化为数字

    父子组件通讯

    重要!!面试常问!!
    我的另一篇详细介绍:https://blog.csdn.net/qq_37215621/article/details/126881423

    生命周期

    • 挂载阶段:
      beforeCreat:执行时,data和methods中的数据都还没有初始化
      created:data和methods都已经初始化好了,此函数可以操作data数据和methods方法
      beforeMount:此函数执行的时候,模板已经在内存中编译好了,但是尚未挂载到页面中去,此时,页面还是旧页面
      mounted: 经将编译好的模板,挂载到了页面指定的容器中显示
    • 更新阶段:
      beforeUpdate:状态更新之前执行此函数, 此时 data 中的状态值是最新的,但是界面上显示的 数据还是旧的,因为此时还没有开始重新渲染DOM节点
      updated:实例更新完毕之后调用此函数,此时 data 中的状态值 和 界面上显示的数据,都已经完成了更新,界面已经被重新渲染好了!
    • 销毁阶段:
      beforeDestroy:实例销毁之前调用。在这一步,实例仍然完全可用。
      destroyed:Vue 实例销毁后调用。调用后,Vue 实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁。

    父子组件生命周期顺序

    口诀:创建从外到内,渲染从内到外


    父先created
    子created
    子mounted
    父mounted


    父beforeUpdate
    子beforeUpdate
    子updated
    父updated


    父beforeDestroy
    子beforeDestroy
    子destroyed
    父destroyed

    $nextTick

    1. vue是异步渲染
    2. data改变,dom不会立刻渲染
    3. $nextTick会在Dom渲染完成之后触发,以获取最新DOM节点
    this.$nextTick(()=>{
    })
    
    • 1
    • 2

    当多次修改data数据时,Vue会做一个data整合进行一次渲染(也就只会调用$nextTick一次)

    slot 插槽

    1. 默认插槽
    //父组件
    <Child>
     <div>
      <h2>hello, child</h2>
     </div>
    </Child>
    
    //子组件
    <template>    
        <div>            
             <slot></slot>   
        </div>
    </template>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    1. 作用域插槽
      子组件向父组件传递数据
    //子组件
    <slot :slotData="val"></slot>
    //父组件
    <Index>
     <template v-slot="receivedSlot">
      <h4>从slot那边接收来的数据:{{receivedSlot.slotData}}</h4>       
      </template>
    </index>
    //receivedSlot.slotData,命名对应父组件receivedSlot和子组件slotData
    
    // Demo
    <slot :str="xxx" :obj="{name: 'zs'}"><slot>
    / 使用
    
    // 组件只有默认插槽,v-slot可以写在组件上,但不能用缩写形式
    <Demo v-solt="data">
      {{data.str}} / {{data.obj.name}}
    </Demo>
    
    // 组件有多个插槽,v-slot写在template上,可以用缩写形式
    <Demo>
      <template #default="data">
        {{data.str}} / {{data.obj.name}}
      </template>
    </Demo>
    
    // 插槽Prop解构
    <template #default="{str, obj}">
      {{str}} / {{obj.name}}
    </template>
    
    // 插槽Prop重命名
    <template #default="{str: text, obj: data}">
      {{text}} / {{data.name}}
    </template>
    
    // 插槽Prop默认值
    <template #default="{str = 'zzz', obj = {name: 'ls'}">
      {{text}} / {{data.name}}
    </template>
    
    • 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
    1. 具名插槽
      在这里插入图片描述
      v-slot只能写在 template 上,当只有默认插槽时组件标签才能当插槽模板使用,v-slot 缩写 #
    <template #default> defalut </template>
    <template #footer> footer </template>
    
    • 1
    • 2

    动态组件

    • 通过 来切换不同的组件
    • 切换的组件不会被缓存,通常配合 来使用
    <div v-for="(item, index) of arr" :key="index">
      <component :is="item" />
    </div>
    
    ...
    import text from 'xxx/text'
    import image from 'xxx/image'
    ...
    data() {
      return {
        arr: ['text', 'image'] // 根据数据的值进行不同组件不同顺序渲染
      }
    }
    ...
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    异步组件

    说明:

    • 当某些组件体积过大,如:代码编辑器、echarts图表,直接全部同步打包会导致体积特别大

    • 通过 import() 函数引入

    • 按需加载,异步加载大组件,使用才加载,不用永远不加载

    <Child v-model="name" v-if="showComponent" />
    <button @click="show">点击显示组件</button>
    
    components: {
       Child: ()=>import('./Child.vue')
     }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    // 全局注册
    
    // 在工厂函数中定义
    Vue.component('async-component', function(resolve, reject) {
      resolve({
        // 组件内容
        template: '
    async-component
    ' }) }) // 配合 webpack 的 code-splitting 功能使用,将构建代码分割成多个包,这些包通过 Ajax 加载 Vue.component('async-component', funcrion(resolve) { require(['xxx/yyy.vue'], resolve) }) // 在工厂函数中直接返回一个 Promise Vue.component('async-component', () => import('xxx/yyy.vue')) // 局部注册 // 返回一个 Promise ... components: { 'async-component': () => import('xxx/yyy.vue') } ... // 返回一个 对象 ... components: { 'async-component': () => ({ component: () => import('xxx/yyy.vue'), // 加载组件 loading: LoadingComponent, // 加载展示组件 error: errorComponent, // 失败展示组件 delay: 200, // 延迟展示时间 timeout: 3000 // 加载超时时间 }) } ...
    • 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

    keep-alive

    • keep-alive 会缓存组件

    • keep-alive 从 vue 即框架层面控制,v-show 从 css 层面来控制

    • keep-alive 再次使用组件不会重新创建和渲染,v-if 每次都会销毁和创建,并创建VNode,执行diff算法
      keep-alive将组件生成的dom缓存起来,下次再重建时直接拿来使用,不执行destroy和mounted

    mixin

    多个组件有相同的逻辑,抽离出来

    //mix.js:
    export default {
        data(){
            return {
                time: new Date()
            }
        },
        methods: {
            getDowtime(){
                console.log('现在时间是:', this.time);
              }
        }
    }
    
    //引入:
    import mix from './mix'
    export default {
      mixins: [mix], //可以添加多个,会自动合并起来
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    问题:

    • 变量来源不明确,不利于阅读。

    • 多mixin可能会造成命名冲突(可能有覆盖的情况)。

    • 多mixin和组件可能会出现多对多的关系,复杂度较高。

  • 相关阅读:
    当当网按关键字搜索dangdang商品 API
    【AI应用】NVIDIA GeForce RTX 3060的详情参数
    可视化Docker管理工具-DockerUI
    带头双向循环链表
    美国服务器租用详细介绍与租用流程
    集成 Redis & 异步任务 - SpringBoot 2.7 .2实战基础
    R语言混合效应(多水平/层次/嵌套)模型及贝叶斯实现技术
    (不开窗)给出employees表中排名为奇数行的first_name
    g++ 重要编译参数
    mysql GRANT创建用户授权
  • 原文地址:https://blog.csdn.net/qq_37215621/article/details/133953735