前端常见面试题(详解)——持续更新中

本文详细介绍了Vue.js的生命周期、Vue.use()、自定义指令、computed与watch的区别、过滤器的使用、Vuex的理解以及父子组件间的交互。此外,还涉及JavaScript中的数据类型、原型链、闭包、this的指向、异步操作处理、事件循环、DOM操作等内容。深入探讨了Vue.js中v-model的实现原理、v-if与v-show的选择、以及v-for循环中key的作用。最后,文章讨论了网络协议、HTTP状态码以及前端性能优化中的重绘和回流。
摘要由CSDN通过智能技术生成

目录

vue

1.vue生命周期

2.vue.use()

3.自定义指令

4.computed和watch有何区别?

5.过滤器的使用filters

6.vuex 的理解

7.父子组件的生命周期钩子

8.v-mode和.sync的对比

9.对nextTick的理解

10.哈希路由和history路由的区别

11. 组件之间的传参方式

12.mutation和action的使用区别

13.vue2中v-model是一个语法糖,那具体是怎么实现的?

14.v-if和v-show的区别

15.循环的时候,为什么一定要绑定key

16.vue2 常用的指令有哪些

17.vue2和vue3的区别

18.vue2中响应式的原理

JS

1.js的数据类型 8种

2.如何判断数据类型 5种

3.原型链

4.闭包

5.如何判断this的指向

6.call和apply 和bind的使用

7.数组常用的api

8.什么是回调地狱,如何解决

9.promise的使用

10.new的背后做哪些事情

11.防抖和节流

12.高阶函数

13.函数柯里化

14.for in和for of的区别

15.递归及应用场景

16.eventloop事件循环

17.深拷贝与浅拷贝

网络

1.https和http的区别

2.常见http的状态码

3.如何减少重绘和回流

4.描述输入url地址到网页展示的过程

5.跨域问题及解决方案

6.get请求和post请求的区别

7.http的协议的三个内容

8.请求头中的contentType有什么用处

 dom

1.事件冒泡和事件捕获

2. 事件委托

3.如何添加和删除事件


vue

1.vue生命周期

Vue 实例从创建到销毁的过程,就是生命周期。也就是从开始创建、初始化数据、编译模板、挂载Dom→渲染、更新→渲染、卸载等一系列过程

初始化  

在beforeCreate生命周期函数执行的时候,data和method 还没有初始化

在created 生命周期函数执行的时候,data和method已经初始化完成

挂载

在beforeMount 生命周期函数执行的时候,已经编译好了模版字符串、但还没有真正渲染页面中

在mounted 生命周期函数执行的时候,已经渲染完,在视图中可以看到页面

更新

在beforeUpdate生命周期函数执行的时候,已经可以拿到最新的数据,但还没渲染到视图中去。

在updated生命周期函数执行的时候,已经把更新后的数据渲染到视图中去了。

销毁

在beforeDestroy 生命周期函数执行的时候,实例进入准备销毁的阶段、此时data 、methods 、指令等还是可用状态 

在destroyed生命周期函数执行的时候,实例已经完成销毁、此时data 、methods 、指令等都不可用 

三个不常用

keep-alive 主要用于保留组件状态或避免重新渲染。

activated只有在keep-alive 组件激活时调用。

deactivated只有在keep-alive 组件停用时调用。

errorCapured 当捕获一个来自子孙组件的错误时被调用。此钩子会收到三个参数:错误对象、发生错误的组件实例以及一个包含错误来源信息的字符串。此钩子可以返回 false 以阻止该错误继续向上传播


2.vue.use()

在 install 里我们可以拿到 Vue 那么和 Vue 相关的周边工作都可以考虑放在 Vue.use() 方法里,比如:

  • directive注册
  • mixin注册
  • filters注册
  • components注册
  • prototype挂载
  • ...

通过全局方法 Vue.use() 使用插件;也可以将使用理解成注册

Vue.use(js对象/function,参数)
js对象:{
    install(Vue,options){
      // 在Vue.use后,该方法会执行  
    }
}
function:function(Vue,options){
  // 在Vue.use后,该方法会执行    
}

常见的注册场景

import Router from 'vue-router'
Vue.use(Router)

import Vuex from 'vuex'
Vue.use(Vuex)

import Echarts from 'echarts'
Vue.prototype.$echarts = Echarts

echarts 用 Vue.use() 来注册

main.js

import Vue from 'vue'
import echarts from './echarts.js'
Vue.use(echarts)

new Vue({
  ...
})

echarts.js

import Echarts from 'echarts'
export default {
  install(Vue){
    Vue.prototype.$echarts = Echarts
  }
}

3.自定义指令

可以看这个  8个非常实用的vue自定义指令

除了默认的内置指令 (v-model 和 v-show)等之外,Vue 也允许注册自定义指令。当我们需要对普通 DOM 元素进行底层操作时,这时候就会用到自定义指令。

指令定义函数提供了几个钩子函数(可选):

  • bind: 只调用一次,指令第一次绑定到元素时调用,用这个钩子函数可以定义一个在绑定时执行一次的初始化动作。

  • inserted: 被绑定元素插入父节点时调用(父节点存在即可调用,不必存在于 document 中)。

  • update: 被绑定元素所在的模板更新时调用,而不论绑定值是否变化。通过比较更新前后的绑定值,可以忽略不必要的模板更新(详细的钩子函数参数见下)。

  • componentUpdated: 被绑定元素所在模板完成一次更新周期时调用。

  • unbind: 只调用一次, 指令与元素解绑时调用。

接下来我们来看一下钩子函数的参数 (包括 elbindingvnodeoldVnode) 。

  • el: 指令所绑定的元素,可以用来直接操作 DOM 。

  • binding   一个对象,包含以下属性 (具体的vue.js文档查看)

  • vnode: Vue 编译生成的虚拟节点,查阅 VNode API 了解更多详情。

  • oldVnode: 上一个虚拟节点,仅在 updatecomponentUpdated 钩子中可用。

除了 el 之外,其它参数都应该是只读的,尽量不要修改他们。如果需要在钩子之间共享数据,建议通过元素的 dataset 来进行

添加一个自定义指令,有两种方式:

  • 通过 Vue.directive() 函数注册一个全局的指令。

  • 通过组件的 directives 属性,对该组件添加一个局部的指令。

创建全局指令:

需要传入指令名称以及一个包含指令钩子函数的对象,该对象的键即钩子函数的函数名,值即函数体,钩子函数可以有多个。

Vue.directive('指令名',{
    自定义指令的生命周期
    bind:绑定时,自定义指令绑定于相应dom时执行(类似于vue生命周期的beforeMount)
    bind(dom,obj,vnode){
        dom:指令所在dom
        obj:{
            属性名
            修饰符
            值
        }
        vnode:虚拟dom节点信息
           context:能获取指令所在组件的实例对象        
    }
    inserted:指令所在dom添加到父节点时执行,渲染时(类似于以前的mounted)
    inserted(dom,obj,vnode){
        
    },
    update:更新时,不保证更新完成(指令所在组件有更新时执行),不保证该更新和当前指令所在dom有关 
    update(dom,obj,vnode){
        dom:当前指令所在dom
        obj:{
            属性名
            修饰符
            值   
        }
        vnode:context:获取指令所在组件的实例对象
    }
    
    componentUpdated:更新完成时,指令所在组件更新完成(类似于以前vue生命周期的updated)
    unbind:解除绑定,类似于beforeDestroy
})

 局部自定义指令

directieves:{
    指令名:{
        bind,
        inserted,
        update,
        componentUpdated,
        unbind
    }
}

应用场景

图片出错的自定义指令。在做过的一个项目中,有一个上传头像的部分,上传了一张图片后,它的地址有错误,就需要自己给定一个默认的图片,有正确的图片就放正确的图片,图片地址错误就放默认的图片。就用到了自定义指令,v-images 当地址是错误的时候,就需要用到自己自定义的一个默认的图片

批量注册指令,新建 directives/index.js 文件

import copy from './copy'
import longpress from './longpress'
// 自定义指令
const directives = {
  copy,
  longpress,
}
 
export default {
  install(Vue) {
    Object.keys(directives).forEach((key) => {
      Vue.directive(key, directives[key])
    })
  },
}

 在 main.js 引入并调用

import Vue from 'vue'
import Directives from './JS/directives'
Vue.use(Directives)

4.computed和watch有何区别?

计算属性computed :

1.computed是依赖已有的变量来计算一个目标变量,大多数情况都是多个变量凑在一起计算出一个变量

2.并且computed具有缓存机制,依赖值不变的情况下其会直接读取缓存进行复用

3.computed不能进行异步操作,当computed内有异步操作时无效,无法监听数据的变化

4.如果computed属性属性值是函数,那么默认会走get方法;函数的返回值就是属性的属性值;在computed中的属性都有一个get和一个set方法,当数据变化时,调用set方法。

5.使用  给计算属性的变量赋值时使用全写      需要进行计算求和的时候使用到

computed: {
    属性名: {
       set(值) {   // set()接收要赋予的值
 
   },
       get() {
         return "值"   // get()里要返回给这个计算属性具体值
   }

  }
}

侦听属性watch:

1.watch是监听某一个变量的变化,并执行相应的回调函数,通常是一个变量的变化决定多个变量的变化

2.不支持缓存,数据变,直接会触发相应的操作

3.watch可以进行异步操作

4.监听数据必须是data中声明过或者父组件传递过来的props中的数据,当数据变化时,触发其他操作,监听的函数接收两个参数,第一个参数是最新的值;第二个参数是输入之前的值;  immediate:组件加载立即触发回调函数执行

deep: 深度监听,为了发现对象内部值的变化,复杂类型的数据时使用

5.使用: 当进行全选与饭选的时候用到

监听一个基本数据时:

watch: {
    value () {
        // do something
    }
}

 监听一个引用数据类型时:

watch: {

    需要监听的属性名 obj: {
       handler (newVal,oldVal) { // 执行回调
           // do something
       },
       deep: true, // 是否进行深度监听 复杂数据类型
       immediate: true // 是否初始执行handler函数, 立即执行
    }
}

总结

当目的是进⾏数值计算,且依赖于其他数据,那么推荐使用 computed

当需要在某个数据发生变化的, 同时做⼀些稍复杂的逻辑操作,那么推荐使⽤ watch


5.过滤器的使用filters

过滤器就是一个函数, 传入值返回处理后的值,被用于转换格式,常见的文本格式化,将值转换为另一种形式

Vue3中舍弃了filters 过滤器,用函数替代了过滤器

过滤器可以用在两个地方:双花括号插值和v-bind表达式

全局的用Vue.filter():Vue.filter("过滤器名", (值) => {return "返回处理后的值"})

局部的用filters属性: filters: {过滤器名字: (值) => {return "返回处理后的值"}

过滤器传参: vue 变量 | 过滤器传参

多个过滤器: vue变量 | 过滤器1 | 过滤器2

应用场景: 时间格式化用到过滤器,有一个禁用和启用的状态改变用到了过滤器,人员员工的聘用形式用到了过滤器:过滤器的名字:function() {return}  导入,全局过滤器注册, 使用{vue变量:过滤器名字}


6.vuex 的理解

vuex的本质是一个对象,是响应式的,管理公共数据的工具,用于多个组件之间的数据共享。vuex的出现是为了解决web组件化开发的过程中,各组件之间传值的复杂和混乱的问题。

 整个虚线部分就是Vuex,我们可以把它看成一个公共仓库store。store中有Actions(行为)、Mutations(变动)和State(状态)。整个的逻辑是组件通过Dispatch调用Actions中的方法,Actions通过Commit调用Mutations中的方法,Mutatisons改变State中的值。

vuex是全局状态管理库,可以通过它来进行全局数据流的管理。

state: 存放多个组件都用得到的公共数据,定义了应用状态的数据结构,可以在这里设置默认的初始状态(相当于data)

mutations: 存放操作数据的方法,修改state (相当于methods)

actions: 存放一些异步操作 (也可以进行一些同步处理) 注意: actions是不能直接修改state数据的, 需要提交mutation

getters: 存放基于state计算出来的一些值 (相当于计算属性)

modules: 分模块, 项目大了, 推荐分模块管理,用到映射,先从vuex中导入mapState,然后使用

注意点: 分模块了, 默认muations, actions, getters 注册到全局的, 一般会开启命名空间,语法: namespaced: true  可以解决不同模块命名冲突的问题,将不同模块的namespaced:true,之后在不同页面中引入getter、actions、mutations时,需要加上所属的模块名。

简述vuex的数据传递流程

当组件进行数据修改的时候,我们需要调用dispatch来触发actions里面的方法。actions里面的每个方法中都会有一个 commit 方法,当方法执行的时候,会通过commit 来触发 mutations 里面的方法来进行数据的修改, mutations 里面的每个函数都会有一个 state 参数, 这样就可以在 mutations 里面进行state 的数据修改, 当数据修改完成后, 会传导给页面,页面的数据也会发生改变。


7.父子组件的生命周期钩子

0. 加载渲染过程

父 beforeCreate 父 created 父 beforeMount

子 beforeCreate 子 created 子 beforeMount 子 mounted 父 mounted

1. 子组件更新过程

子 beforeUpdate 子 updated

2. 父组件更新过程  父组件更新的数据子组件有使用!

父 beforeUpdate 子 beforeUpdate 子 updated 父 updated

3. 销毁过程

父 beforeDestroy 子 beforeDestroy 子 destroyed 父 destroyed


8.v-mode和.sync的对比

v-model 只能使用一次,一个页面中只能使用一次

.async可以使用多次

vue3中没有async 用函数来替代

v-model = " 父组件属性"     就相当于   :value= “父组件的属性” @ input = "父组件的属性" = $event

v-model
   父组件中的子组件标签上   :value="父组件属性&
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值