美文网首页面试vueVue技术
2022年vue面试题总结

2022年vue面试题总结

作者: 小溪流jun | 来源:发表于2022-01-27 15:54 被阅读0次

    vue 中 data 为什么是一个函数

    vue组件是用来复用的,且 JS 里对象是引用关系,如果组件中 data 是一个对象,那么这样作用域没有隔离,子组件中的 data 属性值会相互影响,
    如果组件中 data 选项是一个函数,那么每个实例可以维护一份被返回对象的独立的拷贝,组件实例之间的 data 属性值不会互相影响;
    而 new Vue 的实例,是不会被复用的,因此不存在引用对象的问题。
    

    vue 组件的通信

    ①ref通信
    ②$children
    ③$parent
    ④props和$emit
        ==>async修饰符
        ==>this.$emit("update:变量",需要传递的值)
    ⑤eventBus事件总线
        ==>vue.prototype.$EventBus = new Vue()
        ==>import Vue from 'vue'---export const EventBus = new Vue()
    ⑥provide/inject
    ⑦vuex通信
    ⑧attrs/listeners 适用于 隔代组件通信
        ==>inheritAttrs:false
        ==> <childDomChild v-bind="$attrs" v-on="$listeners"></childDomChild>
    ⑨vue2.6新加的v-slot实现作用域插槽通信:在父组件中使用子组件的数据
        ==><slot name="header" :data='user'>0000000000</slot>
        ==><template v-slot:header='slotprops'> <p>{{slotprops.data}}</p></template>
    
    

    vuex 的原理

    Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。每一个 Vuex 应用的核心就是 store(仓库)。“store” 基本上就是一个容器,它包含着你的应用中大部分的状态 ( state )。
    (1)Vuex 的状态存储是响应式的。当 Vue 组件从 store 中读取状态的时候,若 store 中的状态发生变化,那么相应的组件也会相应地得到高效更新。
    (2)改变 store 中的状态的唯一途径就是显式地提交 (commit) mutation。这样使得我们可以方便地跟踪每一个状态的变化。
    State: 驱动应用的数据源
    Actions: 专门用来与后端backend API打交道
    Mutations: Vuex中专门用于更新state
    Modules:分模块管理vuex
    Getters: 当于组件中的计算属性computed,与state相关,发生变化
    
    1、可以用mapState、mapGetters在computed进行简写。
    2、可以用mapMutations、mapActions在methods进行简写。
    3、this.$store.dispatch触发actions上的方法进行调用后端数据。
    4、this.$store.commit触发mutations上的方法修改state上的变量。
    
    

    vue 生命周期

    vue的生命周期:Vue 实例从创建到销毁的过程;开始创建-->初始化数据-->编译模块-->挂载dom渲染页面-->更新dom渲染页面—>卸载。
    生命周期钩子函数:组件不同阶段会触发相应的钩子函数
    初始化阶段、模板编译阶段、挂载阶段、卸载阶段
    beforecreat
        ==>初始化事件、与data属性进行绑定
        该实例内的所有东西都还没有创建$el,data都是undefined。
    creacted
        ==>判断是否有el,如果有就继续往下编译,如果没有直到在该实例上调用vm.$mount(el)[也就是动态引入了el]。
        render函数>template选项>outer Html-------渲染的一个优先级
    beforeMount
        ==>此时是给vue实例对象添加$el成员,并且替换掉挂载的DOM元素。
    mounted
    beforeUpdate
        ==>当vue发现data中的数据发生变化,会触发对对应组件的重新渲染,
        当数据改变后调用beforeupdata,当渲染完成后调用updated钩子函数。
    updated
    beforeDestroy
        ==>官方解释:Vue 实例销毁后调用。调用后,Vue 实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁。
        移除事件监听器(EventBus.$off, window.addEventListener("scroll", 方法名))、关闭定时器、销毁所有的子实例
    destroyed
    activated
        ==>keep-alive(组件激活时触发)
    deactivated
        ==>keep-alive(组件销毁时触发)
    ErrorCaptured
    
    beforeCreate    组件实例被创建之初,组件的属性生效之前
    created 组件实例已经完全创建,属性也绑定,但真实 dom 还没有生成,$el 还不可用
    beforeMount 在挂载开始之前被调用:相关的 render 函数首次被调用
    mounted el 被新创建的 vm.$el 替换,并挂载到实例上去之后调用该钩子
    beforeUpdate    组件数据更新之前调用,发生在虚拟 DOM 打补丁之前
    update  组件数据更新之后
    activited   keep-alive 专属,组件被激活时调用
    deactivated keep-alive 专属,组件被销毁时调用
    beforeDestory   组件销毁前调用
    destoryed   组件销毁后调用
    

    v-if 与 v-for 的优先级

    当 Vue 处理指令时,v-for 比 v-if 具有更高的优先级;所以不一般不能用于同一个标签上
    每一次判断都需要遍历整个数组,将会十分影响性能
    所以在实际开发中,我们会先判断再循环
    

    v-if 和 v-show 的区别

    ①v-if是通过控制dom节点的存在与否来控制元素的显隐;v-show是通过设置DOM元素的display样式,block为显示,none为隐藏
    ②v-if切换有一个局部编译/卸载的过程,切换过程中合适地销毁和重建内部的事件监听和子组件;v-show只是简单的基于css切换;
    如果是频繁的切换用v-show,否则用v-if
    

    vue 中 key 的作用

    1、key的作用主要是为了高效的更新虚拟DOM
    2、不能使用index作为v-for中的key;你删除一个数组长度为3的第二项,vue会认为你删除的是第三项,因为index也是连续的
    3、当页面的数据发生变化时,Diff算法只会比较同一层级的节点
    4、有相同父元素的子元素必须有独特的 key。重复的 key 会造成渲染错误
    
    

    虚拟 dom

    virtual DOM:是将真实的DOM的数据抽取出来,以对象的形式模拟树形结构
    template模板(编译)==>渲染函数(执行)==>虚拟dom==>patch(patching算法)==>真实dom(视图)
    虚拟DOM的最终目标是将虚拟节点渲染到视图上
    
    

    diff 算法

    diff的过程就是调用名为patch的函数,比较新旧节点,一边比较一边给真实的DOM打补丁
    虚拟DOM最核心的部分,它可以将vnode渲染成真实的DOM
    1、用 JavaScript 对象结构表示 DOM 树的结构;然后用这个树构建一个真正的 DOM 树,插到文档当中
    2、当状态变更的时候,重新构造一棵新的对象树。然后用新的树和旧的树进行比较,记录两棵树差异
    3、把所记录的差异应用到所构建的真正的DOM树上,视图就更新了
    

    conputed 和 watch 的区别

    conputed
    1. 支持缓存,只有依赖数据发生改变,才会重新进行计算
    2. 不支持异步,当computed内有异步操作时无效,无法监听数据的变化
    3.computed 属性值会默认走缓存,计算属性是基于它们的响应式依赖进行缓存的,也就是基于data中声明过或者父组件传递的props中的数据通过计算得到的值
    4. 如果一个属性是由其他属性计算而来的,这个属性依赖其他属性,是一个多对一或者一对一,一般用computed
    5.如果computed属性属性值是函数,那么默认会走get方法;函数的返回值就是属性的属性值;在computed中的,属性都有一个get和一个set方法,当数据变化时,调用set方法。
    watch
    1. 不支持缓存,数据改变,直接会触发相应的操作;
    2.watch支持异步;
    3.监听的函数接收两个参数,第一个参数是最新的值;第二个参数是输入之前的值;
    4. 当一个属性发生变化时,需要执行对应的操作;一对多;
    5. 监听数据必须是data中声明过或者父组件传递过来的props中的数据,当数据变化时,触发其他操作,函数有两个参数,
    immediate:组件加载立即触发回调函数执行,
    deep: 深度监听,为了发现对象内部值的变化,复杂类型的数据时使用,例如数组中的对象内容的改变,注意监听数组的变动不需要这么做。注意:deep无法监听到数组的变动
    

    vue 的自定义指令

    {{}}插值语法
    v-html插入html片段,可以防止xss攻击,类似innerHTML
    v-once只渲染一次
    v-text插入文本,不解析html,类似innerText
    v-model 在表单元素上实现:双向数据绑定
        ==>v-bind绑定一个value属性;v-on指令给当前元素绑定input事件。
    v-on
    v-bind
    v-show
    v-if
    v-else-if
    v-else
    v-for
    
    

    $nextTick

    ==>在js中属于微任务
    ==>$nextTick 是在下次 DOM 更新循环结束之后执行延迟回调,在修改数据之后使用 $nextTick,则可以在回调中获取更新后的 DOM,
    ==>Vue生命周期的created()钩子函数进行的DOM操作一定要放在Vue.nextTick()的回调函数中,原因是在created()钩子函数执行的时候DOM 其实并未进行任何渲染,
    而此时进行DOM操作无异于徒劳
    

    v-on 可以监听多个方法

    <input type="text" v-on="{ input:onInput,focus:onFocus,blur:onBlur, }">
    

    keep-alive

    keep-alive 是 Vue 内置的一个组件,可以使被包含的组件保留状态,或避免重新渲染。
    实现keep-alive的方式
    1、  <router-view v-if="$route.meta.keepAlive"></router-view>
    2、include等于组件名:<keep-alive include="test-keep-alive">
      <!-- 将缓存name为test-keep-alive的组件 -->
      <component></component>
    </keep-alive>
    
    

    路由跳转传参 params 和 query 的区别

    1、接收参数的方式不同
        ==>this.$route.params/this.$route.query
    2、query的方法传参url路径会显示传递的参数
    3、params刷新页面会丢失参数
    4、params是用name属性,query是用path属性来编写传参地址
    
    

    router和route

    $router:$router对象是全局路由的实例,是router构造方法的实例
    $route:$route对象表示当前的路由信息,包含了当前 URL 解析得到的信息。包含当前的路径,参数,query对象等
    this.$router.push()
    this.$router.replace()
    this.$router.go(n)
    this.$router.back()
    

    Vue-router 跳转和 location.href 有什么区别

    ①vue-router使用pushState进行路由更新,静态跳转,页面不会重新加载;location.href会触发浏览器,页面重新加载一次
    ②vue-router使用diff算法,实现按需加载,减少dom操作
    ③vue-router是路由跳转或同一个页面跳转;location.href是不同页面间跳转;
    ④vue-router是异步加载this.$nextTick(()=>{获取url});location.href是同步加载
    
    

    Vue-router 导航守卫有哪些

    beforeRouteEnter(to, from,) {
        console.log("to", to)
        console.log("from", from)
        console.log("next", next)
        next(vm => {
        // 通过 `vm` 访问组件实例
        })
        // 在渲染该组件的对应路由被 confirm 前调用
        // 不!能!获取组件实例 `this`
        // 因为当守卫执行前,组件实例还没被创建
    },
    beforeRouteUpdate(to, from, next) {
        // 在当前路由改变,但是该组件被复用时调用
        // 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,
        // 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
        // 可以访问组件实例 `this`
    },
    beforeRouteLeave(to, from, next) {
        // 导航离开该组件的对应路由时调用
        // 可以访问组件实例 `this`
    },
    //全局的前置路由
    router.beforeEach
    

    vue-router 中常用的 hash 和 history 路由模式实现原理

    //hash 路由
    早期的前端路由的实现就是基于 location.hash 来实现的。其实现原理很简单,location.hash 的值就是 URL 中 # 后面的内容。比如下面这个网站,它的 location.hash 的值为 '#search':
    以使用 hashchange 事件来监听 hash 值的变化,从而对页面进行跳转(渲染)
    // history 路由
    history.pushState() 和 history.repalceState()。这两个 API 可以在不进行刷新的情况下,操作浏览器的历史纪录。唯一不同的是,前者是新增一个历史记录,后者是直接替换当前的历史记录
    pushState 和 repalceState 两个 API 来操作实现 URL 的变化 ;
    以使用 popstate 事件来监听 url 的变化,从而对页面进行跳转(渲染)
    history.pushState() 或 history.replaceState() 不会触发 popstate 事件,这时我们需要手动触发页面跳转(渲染)。
    

    vuex 和 localStorage 的区别

    1、vuex的数据刷新页面会丢失,而localStorage的数据是永久存储的,除非手动清除。
    2、vuex存储在内存,localstorage(本地存储)则以文件的方式存储在本地,永久保存;
    sessionstorage( 会话存储 ) ,临时保存。localStorage和sessionStorage只能存储字符串类型,
    对于复杂的对象可以使用ECMAScript提供的JSON对象的stringify和parse来处理
    3、应用场景:vuex用于组件之间的传值,localstorage,sessionstorage则主要用于不同页面之间的传值。
    4、vuex的数据是响应式的
    5、localstorage无法存储function.
    

    vue 中的动态路由

    像后台管理系统的左边菜单的导航栏,要做角色权限的一个控制;路由由后端返回
    简单的角色权限:管理员权限和普通用户
    复杂的路由权限:OA系统,门店用户,个人用户,区域用户
    

    vue 的插槽 v-slot

    父组件需要在子组件内放一些DOM,那么这些DOM是显示、不显示、在哪个地方显示、如何显示,就是slot分发负责的活。
    在vue2.6版本以上使用v-slot代替了slot 和 scope-slot ,vue3.0中也弃用了。
    v-slot 只能添加到template 或自定义组件上
    可以在子组件上写插槽的默认内容:<slot name='header'>11111111111</slot>
    1、默认的插槽
        ==>任何没有被包裹在带有 v-slot 的 组件标签 中的内容都会被视为默认插槽的内容。
                没有名字的 隐含有一个 “default” 名称
    2、具名插槽
        ==><template v-slot:header> <p>111111111</p> </template>
        ==><template #header> <p>111111111</p> </template>
    3、作用域插槽
        ==><slot name="header" :data='user'>0000000000</slot>
        ==><template v-slot:header='slotprops'> <p>{{slotprops.data}}</p></template>
    4、动态插槽名
        ==><template v-slot:[dynamicSlotName]> 00000000 </template>
    1、父级模板里的所有内容都是在父级作用域中编译的;子模板里的所有内容都是在子作用域中编译的。
    2、<slot></slot>标签里面的内容会作为后备内容且有默认的名字default
    3、(特殊:独占默认插槽的缩写语法)---只要出现多个插槽,请始终为所有的插槽使用完整的基于 <template> 的语法,v-slot 只能添加在 <template> 上
    4、作用域插槽:绑定在 <slot> 元素上的 attribute 被称为插槽 prop
    5、#简写: #default="{ user }"
    

    vue 中的混入 minx

    1、混入对象的钩子将在组件自身钩子之前调用。
    mixins:局部混入
    mixin:全局混入,一旦使用全局混入对象,将会影响到所有之后创建的 Vue 实例
    

    vue 中的过滤器

    双花括号插值
    1、 当有局部和全局两个名称相同的过滤器时候,会以就近原则进行调用,即:局部过滤器优先于全局过滤器被调用!
    2、 一个表达式可以使用多个过滤器。过滤器之间需要用管道符“|”隔开。其执行顺序从左往右
    

    请谈谈你对 mvvm 的理解

    vue是实现了双向数据绑定的mvvm框架,当视图改变更新模型层,当模型层改变更新视图层。在vue中,使用了双向绑定技术,就是View的变化能实时让Model发生变化,而Model的变化也能实时更新到View。
    MVVM 由 Model、View、ViewModel 三部分构成
    Model: 代表数据模型,也可以在 Model 中定义数据修改和业务逻辑;
    View :代表 UI 组件,它负责将数据模型转化成 UI 展现出来;
    ViewModel :是一个同步View 和 Model的对象;
    响应式开发
    组件化开发
    Vue的核心思想就是数据驱动页面,所谓数据驱动,就是页面的dom结构由数据的映射产生,开发者不用去管界面的渲染,只需要管理数据的修改
    
    //暴露的问题
    1、开发者在代码中大量调用相同的 DOM API, 处理繁琐 ,操作冗余,使得代码难以维护。
    2、大量的DOM 操作使页面渲染性能降低,加载速度变慢,影响用户体验。
    3、当 Model 频繁发生变化,开发者需要主动更新到View ;当用户的操作导致 Model 发生变化,开发者同样需要将变化的数据同步到Model 中,这样的工作不仅繁琐,而且很难维护复杂多变的数据状态。
    
    Vue.js 可以说是MVVM 架构的最佳实践,VUE并没有完全遵循MVVM,专注于 MVVM 中的 ViewModel,不仅做到了数据双向绑定,而且也是一款相对比较轻量级的JS 库,API 简洁,很容易上手
    

    MVC

    MVC 是 Model-View-Controller 的缩写,即 模型—视图—控制器 。
    Model:后端传递的 数据 。
    View:所看到的 页面 。
    Controller:页面 业务逻辑 。
    

    v-model 双向数据绑定的原理

    ue数据双向绑定是通过数据劫持结合发布者-订阅者模式的方式来实现。
    数据劫持的实现主要依赖于Object.defineProperty(),通过这个函数可以监听到get,set事件。
    其中observer是最主要的部分,
    用Object.defineProperty来实现数据的劫持,
    然后用他的set,get方法来通知订阅者,触发update方法,从而实现更新视图
    Object.defineProperty()
        ==>给对象添加一个属性并指定该属性的配置。
    vue 双向数据绑定是通过 数据劫持 结合 发布订阅模式的方式来实现的, 也就是说数据和视图同步,数据发生变化,视图跟着变化,视图变化,数据也随之发生改变;
    核心:关于VUE双向数据绑定,其核心是 Object.defineProperty()方法。
    

    vue 中的修饰符

    //事件修饰符
        .stop 阻止单机事件冒泡
        .prevent 阻止默认行为(比如 @submit.prevent 会阻止提交后刷新页面)
        .capture 添加事件侦听器时使用捕获模式
        .self 只有事件在元素本身(而不是子元素)触发时触发回调
        .once 只触发一次(组件也适用)
        .key 触发事件的按键
        .native 原生点击事件
    //v-model 修饰符
        .lazy在输入框中,默认是在input事件中同步输入框的数据,使用 lazy修饰符会转变为在change事件中同步(失去焦点或按回车才更新)。
        . number将输入转换为Number类型,默认是String
        .trim 自动过滤输入的首尾空格
    
    

    vue 中的自定义指令

    directives: 自定义指令
    有三个钩子函数
    bind:只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。
    inserted:被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)。
    update:所在组件的 VNode 更新时调用,但是可能发生在其子 VNode 更新之前。指令的值可能发生了改变,也可能没有。
    el, binding, vnode,oldVnode:四个函数的入参
    //el:指令所绑定的元素,可以用来直接操作 DOM。
    //binding:一个对象,包含以下 property:
    //vnode:Vue 编译生成的虚拟节点。移步 VNode API 来了解更多详情。
    //oldVnode:上一个虚拟节点,仅在 update 和 componentUpdated 钩子中可用。
    

    vue 框架的优点

    轻量级框架:只关注视图层,是一个构建数据的视图集合,大小只有几十kb;
    简单易学:国人开发,中文文档,不存在语言障碍 ,易于理解和学习;
    双向数据绑定:保留了angular的特点,在数据操作方面更为简单;
    组件化:保留了react的优点,实现了html的封装和重用,在构建单页面应用方面有着独特的优势;
    视图,数据,结构分离:使数据的更改更为简单,不需要进行逻辑代码的修改,只需要操作数据就能完成相关操作;
    虚拟DOM:dom操作是非常耗费性能的, 不再使用原生的dom操作节点,极大解放dom操作,但具体操作的还是dom不过是换了另一种方式;
    运行速度更快:相比较与react而言,同样是操作虚拟dom,就性能而言,vue存在很大的优势。
    

    vue-loader 是什么

    vue文件的一个加载器,将template/js/style转换成js模块。
    用途:js可以写es6、style样式可以scss或less、template可以加jade等
    

    axios 的特点有哪些

    从浏览器中创建XMLHttpRequests;
    node.js创建http请求;
    支持Promise API;
    拦截请求和响应;
    转换请求数据和响应数据;
    取消请求;
    自动换成json。
    axios中的发送字段的参数是data跟params两个,两者的区别在于params是跟请求地址一起发送的,data的作为一个请求体进行发送
    params一般适用于get请求,data一般适用于post put 请求。
    

    封装 vue 组件的过程

    1. 建立组件的模板,先把架子搭起来,写写样式,考虑好组件的基本逻辑。(os:思考1小时,码码10分钟,程序猿的准则。)
    2. 准备好组件的数据输入。即分析好逻辑,定好 props 里面的数据、类型。
    3. 准备好组件的数据输出。即根据组件逻辑,做好要暴露出来的方法。
    4. 封装完毕了,直接调用即可
    

    面对对象思想

    面向对象的方法就是利用抽象、封装等机制,借助于对象、类、继承、消息传递等概念进行软件系统构造的软件开发方法。
    面向对象,将所需要做的功能抽象成一个“对象”,然后反复调用这个对象来完成你想要的功能
    
    

    vue 初始化页面闪动问题

    在css里加上[v-cloak] {
    display: none;
    }。
    如果没有彻底解决问题,则在根元素加上style="display: none;" :style="{display: 'block'}"
    

    vue-router 实现路由懒加载

    结合 Vue 的异步组件 (opens new window)和 Webpack 的代码分割功能 (opens new window),轻松实现路由组件的懒加载
    第一种:vue异步组件技术 ==== 异步加载,vue-router配置路由 , 使用vue的异步组件技术 , 可以实现按需加载 .但是,这种情况下一个组件生成一个js文件。
    第二种:路由懒加载(使用import)。
    第三种:webpack提供的require.ensure(),vue-router配置路由,使用webpack的require.ensure技术,也可以实现按需加载。这种情况下,多个路由指定相同的chunkName,会合并打包成一个js文件。
    

    SPA 单页面的理解

    优点:
    
    用户体验好、快,内容的改变不需要重新加载整个页面,避免了不必要的跳转和重复渲染;
    
    基于上面一点,SPA 相对对服务器压力小;
    
    前后端职责分离,架构清晰,前端进行交互逻辑,后端负责数据处理;
    
    缺点:
    
    初次加载耗时多:为实现单页 Web 应用功能及显示效果,需要在加载页面的时候将 JavaScript、CSS 统一加载,部分页面按需加载;
    
    前进后退路由管理:由于单页应用在一个页面中显示所有的内容,所以不能使用浏览器的前进后退功能,所有的页面切换需要自己建立堆栈管理;
    
    SEO 难度较大:由于所有的内容都在一个页面中动态替换显示,所以在 SEO 上其有着天然的弱势。
    

    Vue 的单向数据流

    所有的 prop 都使得其父子 prop 之间形成了一个单向下行绑定:父级 prop 的更新会向下流动到子组件中,但是反过来则不行。
    
    这样会防止从子组件意外改变父级组件的状态,从而导致你的应用的数据流向难以理解。
    
    额外的,每次父级组件发生更新时,子组件中所有的 prop 都将会刷新为最新的值。这意味着你不应该在一个子组件内部改变 prop。如果你这样做了,Vue 会在浏览器的控制台中发出警告。
    
    子组件想修改时,只能通过 $emit 派发一个自定义事件,父组件接收到后,由父组件修改。
    

    Vue 的父组件和子组件生命周期钩子函数执行顺序

    Vue 的父组件和子组件生命周期钩子函数执行顺序可以归类为以下 4 部分:
    
    加载渲染过程
    
    父 beforeCreate -> 父 created -> 父 beforeMount ->
     子 beforeCreate -> 子 created -> 子 beforeMount ->
    子 mounted -> 父 mounted
    
    子组件更新过程
    
    父 beforeUpdate -> 子 beforeUpdate -> 子 updated -> 父 updated
    
    父组件更新过程
    
    父 beforeUpdate -> 父 updated
    
    销毁过程
    
    父 beforeDestroy -> 子 beforeDestroy -> 子 destroyed -> 父 destroyed
    !!!子组件的updated 、mounted 和destroyed 优先于父组件执行
    

    SSR 服务器渲染

     BSR 客户端渲染(前后端分离):视图与数据的组装是在客户端完成的
    SSR 服务器渲染(前后端不分离):视图和数据的组装是在服务端完成的
    BSR的优势和劣势有哪些?
        服务器压力小
      前后端分离,代码更容易维护
      数据化应用,交互更加丰富
      前端工程师来讲价值更高
      在ToC产品上应用更广泛
    SSR的优势和劣势有哪些?
      前后端不分离,对后端的要求非常高
      有利于SEO
      对客户端的压力比较小,服务器压力较大
      在ToB产品上应用比较广泛
    
    

    vue 项目的前端代码优化

    路由懒加载
    图片懒加载:data-src
    cdn静态资源加速
    第三方插件的按需引入
    开启gzip压缩
    
    防抖和节流
    减少回流和重绘呀
    v-if和v-show的使用
    离开路由时销毁定时器和监听事件
    keep-alive
    
    

    vue3 有了解吗

    (1)监测机制的改变:Proxy 替换了Object.defineProperty 去监听数据的变化
    (2)模板: 3.0 把作用域插槽改成了函数的方式,这样只会影响子组件的重新渲染,提升了渲染的性能。
    (3)对象式的组件声明方式:3.0 修改了组件的声明方式,改成了类式的写法
    Vue 3.0 正走在发布的路上,Vue 3.0 的目标是让 Vue 核心变得更小、更快、更强大,因此 Vue 3.0 增加以下这些新特性:
    Proxy 的优势如下:
    
    Proxy 可以直接监听对象而非属性;($set)
    
    Proxy 可以直接监听数组的变化;
    
    Proxy 有多达 13 种拦截方法,不限于 apply、ownKeys、deleteProperty、has 等等是 Object.defineProperty 不具备的;
    
    Proxy 返回的是一个新对象,我们可以只操作新的对象达到目的,而 Object.defineProperty 只能遍历对象属性直接修改;
    
    Proxy 作为新标准将受到浏览器厂商重点持续的性能优化,也就是传说中的新标准的性能红利;
    
    Object.defineProperty 的优势如下:
    
    兼容性好,支持 IE9,而 Proxy 的存在浏览器兼容性问题,而且无法用 polyfill 磨平,因此 Vue 的作者才声明需要等到下个大版本( 3.0 )才能用 Proxy 重写。
    
    

    webpack

    本质上,webpack 是一个现代 JavaScript 应用程序的静态模块打包器
    入口(entry):
    输出(output):
    loader:
    插件(plugins):目的在于解决 loader 无法实现的其他事
    
    Webpack打包顺序流程
    1.初始化参数:读取命令行传入或者webpack.config.js文件,初始化本次构建的配置参数
    2.开始编译 用上一步得到的参数初始Compiler对象,加载所有配置的插件,通过执行对象的run方法开始执行编译
    3.确定入口 根据配置中的 Entry 找出所有入口文件
    4.编译模块 从入口文件出发,调用所有配置的 Loader 对模块进行编译,再找出该模块依赖的模块,再递归本步骤直到所有入口依赖的文件都经过了本步骤的处理
    5.完成模块编译 在经过第4步使用 Loader 翻译完所有模块后, 得到了每个模块被编译后的最终内容及它们之间的依赖关系
    6.输出资源 根据入口和模块之间的依赖关系,组装成一个个包含多个模块的 Chunk,再将每个 Chunk 转换成一个单独的文件加入输出列表中,这是可以修改输出内容的最后机会
    7.输出完成 在确定好输出内容后,根据配置确定输出的路径和文件名,将文件的内容写入文件系统中。
    
    

    webpack 的常见 loader

    file-loader:把文件输出到一个文件夹中,在代码中通过相对 URL 去引用输出的文件
    url-loader:和 file-loader 类似,但是能在文件很小的情况下以 base64 的方式把文件内容注入到代码中去
    source-map-loader:加载额外的 Source Map 文件,以方便断点调试
    image-loader:加载并且压缩图片文件
    babel-loader:把 ES6 转换成 ES5
    css-loader:加载 CSS,支持模块化、压缩、文件导入等特性
    style-loader:把 CSS 代码注入到 JavaScript 中,通过 DOM 操作去加载 CSS。
    eslint-loader:通过 ESLint 检查 JavaScript 代码
    

    相关文章

      网友评论

        本文标题:2022年vue面试题总结

        本文链接:https://www.haomeiwen.com/subject/xysahrtx.html