【前端面试题——vue3篇】

慈云数据 2024-03-12 技术支持 106 0

目录

    • 1.v-show和v-if指令的共同点和不同点
    • 2.vue组件中data为什么必须是一个函数
    • 3.$nextTick的使用
    • 4.Vue中双向数据绑定是如何实现的
    • 5.v-if和v-for的优先级
    • 6.vue常用的修饰符
    • 7.自定义指令详解
    • 8.vue slot
    • 9.vue初始化页面闪动问题
    • 10.vue更新数组时触发视图更新的方法
    • 11.Vue2.0 和 Vue3.0 有什么区别
    • 12.Vue3带来了什么改变
    • 13.reactive与ref的区别
    • 14.计算属性和watch以及methods的区别
    • 15.$route 和 $router 的区别
    • 16.v-model的使用
    • 17.v-on可以监听多个方法吗
    • 18.vue中过滤器有什么作用及详解
    • 19.EventBus注册在全局上时路由切换时会重复触发事件,如何解决
    • 20.vuex有哪几种属性
    • 21.请详细说下你对vue生命周期的理解
    • 22.vue优点
    • 23.单页面应用和多页面应用区别及优缺点
    • 24.vue路由跳转传参的方式有哪些
    • 25.vue遇到的坑,如何解决的
    • 26.vue封装通用组件方法思路
    • 27.Vue.js中ajax请求代码应该写在组件的methods中还是vuex的actions中
    • 28.Vuex中如何异步修改状态
    • 29.刷新浏览器后,Vuex的数据是否存在?如何解决
    • 30.vuex中的辅助函数怎么使用
    • 31.vue插槽?
    • 32.vue3中如何获取refs,dom对象的方式?
    • 33.vue3中生命周期的和vue2中的区别?
    • 34.说说vue中的diff算法?
    • 35.说说 Vue 中 CSS scoped 的原理?
    • 36.vue3中怎么设置全局变量?
    • 37.Vue中给对象添加新属性时,界面不刷新怎么办?
    • 38.谈谈对Vue中双向绑定的理解?
    • 39.为什么vue2和vue3语法不可以混用?
    • 40.vue3中setup函数如何进行组件通讯?
    • 41.vue3,Composition API 的优势?
    • 42.shallowReactive和shallowRef的区别
    • 43.provide与inject如何使用
    • 44.toRaw 与 markRaw是什么作用?
    • 45.readonly 与 shallowReadonly谈谈你对他的理解?
    • 46.自定义hook是什么?
    • 47.虚拟DOM一定更快吗?
    • 48.vue路由中,history和hash两种模式有什么区别?

      1.v-show和v-if指令的共同点和不同点

      当条件改变的时候v-if是通过DOM节点的添加和删除来控制节点的显示隐藏的,

      【前端面试题——vue3篇】
      (图片来源网络,侵删)

      v-show是通过CSS样式控制节点的显示隐藏的。

      v-if的切换成本比较高,v-show渲染成本比较高,

      【前端面试题——vue3篇】
      (图片来源网络,侵删)

      所以当切换频繁的时候使用v-show,如果初次渲染数据较多的时候,使用v-if

      2.vue组件中data为什么必须是一个函数

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

      如果data是一个函数的话,这样每复用一次组件,就会返回一份新的data(类似于给每个组件实例创建一个私有的数据空间,让各个组件实例维护各自的数据)

      Object是引用数据类型,里面保存的是内存地址,单纯的写成对象形式,就使得所有组件实例共用了一份data,就会造成一个变了全都会变的结果

      3.$nextTick的使用

      vue的$nextTick其本质是对js执行原理EventLoop的一种应用。

      $nextTick的核心是利用promise,mutationObserver、setImmediate、setTimeout的原生

      javascript方法来模拟对应的微/宏任务的实现,本质是为了利用JavaScript的这些异步回调任务队列来实现vue框架中自己的异步回调队列。

      nextTick是典型的将底层的javascript执行原理应用到具体案例中的示例,引入异步更新队列机制的原因:

      • 如果是同步更新,则多次对一个或者多个属性赋值,会频繁触发dom的渲染,可以减少一些无用的渲染。
      • 同时由于virtualDom的引入,每一次状态发生变化之后,状态变化的信号会发送给组件,组件内部使用virtualDom进行计算得出需要更新的具体的dom节点,然后对dom进行更新操作,每次更新状态后的渲染过程需要更多的计算,而这种无用功也将浪费更多的性能,所以异步渲染变得更加至关重要。
      • vue采用了数据驱动的思想,但是在一些情况下,仍然需要操作dom。有时候,可能遇到这样的情况,dom1的数据发生了变化,而dom2需要从dom1中获取数据,那这时候就会发现dom2的试图并没有更新,这时就需要用到nextTick了。

        4.Vue中双向数据绑定是如何实现的

        vue2.0

        vue2.0的双向数据绑定是通过数据劫持,结合发布订阅的方式来实现的,也就是说数据和视图同步,数据发生变化,视图也会发生变化,视图变化,数据也会随之发生改变。vue2的双向数据绑定核心是object.definedproperty()方法。给vue中的数据绑定get和set方法,当获取数据的时候,调用get方法,当修改数据的时候调用set方法。通过watcher监听器去更新视图,完成数据的双向绑定。

        vue3.0

        Object.defineProperty 的问题:在Vue中,Object.defineProperty无法监控到数组下标的变化,导致直接通过数组的下标给数组设置值,不能实时响应。目前只针对以上方法做了hack处理,所以数组属性是检测不到的,有局限性Object.defineProperty只能劫持对象的属性,因此我们需要对每个对象的每个属性进行遍历。Vue里,是通过递归以及遍历data对象来实现对数据的监控的,如果属性值也是对象那么需要深度遍历,显然如果能劫持一个完整的对象,不管是对操作性还是性能都会有一个很大的提升。

        Proxy的两个优点:可以劫持整个对象,并返回一个新对象,有13种劫持。

        5.v-if和v-for的优先级

        v-if 指令用于条件性地渲染一块内容。这块内容只会在指令的表达式返回 true值的时候被渲染。

        v-for 指令基于一个数组来渲染一个列表。v-for 指令需要使用 item in items 形式的特殊语法,其中 items 是源数据数组或者对象,而 item 则是被迭代的数组元素的别名。

        在 v-for 的时候,建议设置key值,并且保证每个key值是独一无二的,这便于diff算法进行优化。

        在vue中,永远不要把v-if和v-for同时用在同一个元素上,会带来性能方面的浪费。

        vue 2.x:当 v-if 与 v-for 一起使用时,v-for 具有比 v-if 更高的优先级

        vue 3.x:当 v-if 与 v-for 一起使用时,v-if 具有比 v-for 更高的优先级。

        6.vue常用的修饰符

        事件修饰符:

        stop(阻止事件冒泡)

        prevent(阻止默认行为)

        self(只触发本身)

        once(只触发一次)

        captrue(事件捕获,与事件冒泡的方向相反,事件捕获由外向内。)

        表单修饰符:

        lazy(当光标离开标签之后,才会赋值给value)

        trim(过滤掉两边的空格)

        number(自动将用户输入的值转化为数值类型。)

        键盘修饰符:

        普通键(enter、tab、delete、space、esc、up…)

        系统修饰键(ctrl、alt、meta、shift…)

        鼠标修饰符:lefft,right,middle

        7.自定义指令详解

        除了我们常用的核心的默认内置的指令像是v-model,v-show,v-if等,vue也允许我们自定义指令,有的情况下,对普通dom元素进行底层操作,这个时候就需要自定义指令。

        自定义指令时用来操作dom的,尽管vue推崇的是数据驱动视图的理念,但并不是所有的情况都适合数据驱动。自定义指令就是一种有效的补充和扩展,不仅可用于任何dom操作,而且是可复用的。

        自定义指令分为两种:一种是自定义的局部指令,一种是全局指令

        8.vue slot

        slot又名插槽,是vue的内容分发机制,组件内部的模板引擎使用slot元素作为承载分发内容的出口。插槽slot是子组件的一个模板标签元素,而在一个标签元素是否显示,以及怎么显示是父组件决定的。

        slot又分为三类,默认插槽,具名插槽,作用域插槽。

        • 默认插槽:又称匿名插槽,当slot没有指定name属性值的时候,一个组件内只能有一个匿名插槽。
        • 具名插槽:带有具体名字的插槽,也就是带有name属性的slot,一个组件可以出现多个具名插槽。
        • 作用域插槽:默认插槽,剧名插槽的一个变体,可以是匿名插槽,也可以是具名插槽,该插槽的不同点在子组件渲染作用域插槽时,可以将子组件内部的数据传递给父组件,让父组件根据子组件传递过来的数据决定如何渲染该插槽。

          9.vue初始化页面闪动问题

          当网速较慢,vue.js文件还没有加载完时,在页面上会显示{{message}}的字样,知道vue创建实例,编译模板时,dom才会被替换,所以这个过程屏幕是闪动的。

          所以解决这个问题,需要在style样式中设置【v-cloak】{display:none}。在一般情况下,v-clock是一个解决初始化慢导致页面闪动的最佳实践,对于简单的项目很实用。

          但是在具有工程化的项目里,比如使用了webpack和vue-router的项目中,html结构只是一个空的div元素,剩余的内容都是由路由去挂载不同的组件完成的,所以不需要v-cloak。

          10.vue更新数组时触发视图更新的方法

          • vue.set相应式新增与修改数据可以设置对象或数组的值,通过key或数组索引,可以触发视图更新。

          • vue.delete,删除对象或数组中元素,通过key或者数组索引,可以触发视图更新。

          • 数组对象直接修改属性,可以触发视图更新

          • 数组整体修改,可以触发视图更新

            Vue包含一组观察数组变异的方法,使用它们改变数组也会触发视图更新不变异的方法:

              • push() 向数组的末尾添加一个或多个元素,并返回新的长度。
                • pop() 删除最后一个元素,把数组长度减 1,并且返回它删除的元素的值。
                  • shift() 把数组的第一个元素从其中删除,并返回第一个元素的值。
                    • unshift() 向数组的开头添加一个或更多元素,并返回新的长度。
                      • splice() 向/从数组中添加/删除项目,然后返回被删除的项目。 该方法会改变原始数组。
                        • sort() 对数组的元素进行排序。
                          • reverse() 颠倒数组中元素的顺序。

                            不变异的方法:

                            • filter()
                            • concat()
                            • slice()

                              他们返回的是一个新数组,使用这些方法时,可以用新数组来替换原始数组

                              11.Vue2.0 和 Vue3.0 有什么区别

                              • 性能:Vue 3 比 Vue 2 更快,因为它采用了新的渲染引擎,这使得它在大型应用程序中更快。
                              • 语法:Vue 3 使用了更简单的语法,并移除了一些 Vue 2 中的不常用功能,这使得代码更容易维护和阅读。
                              • 设计:Vue 3 采用了更加模块化的设计,把各个组件的功能分离开,使得应用程序更加灵活和可扩展。
                              • TypeScript 支持:Vue 3 原生支持 TypeScript,可以更轻松地与其他 TypeScript 项目集成。
                              • Composition API:Vue 3 引入了 Composition API
                              • Vue2 在模板中如果使用多个根节点时会报错,

                                Vue3 支持多个根节点,也就是 fragment

                                12.Vue3带来了什么改变

                                vue3.0对vue的主要3个特点:响应式、模板、对象式的组件声明方式,进行了全面的更改,底层的实现和上层的api都有了明显的变化,基于Proxy重新实现了响应式,基于treeshaking内置了更多功能,提供了类式的组件声明方式。而且源码全部用typescript重写

                                13.reactive与ref的区别

                                • 从定义数据角度对比:

                                  ref用来定义:基本类型数据

                                  reactive用来定义对象(或数组)类型数据

                                  备注:ref也可以用来定义对象(或数组)类型数据, 它内部会自动通过reactive转为代理对象。

                                • 从原理角度对比:

                                  ref通过Object.defineProperty()的get与set来实现响应式(数据劫持)。

                                  reactive通过使用Proxy来实现响应式(数据劫持), 并通过Reflect操作源对象内部的数据。

                                • 从使用角度对比:

                                  ref定义的数据:操作数据需要.value,读取数据时模板中直接读取不需要.value。

                                  reactive定义的数据:操作数据与读取数据:均不需要.value。

                                  14.计算属性和watch以及methods的区别

                                  • 作用机制上:

                                    watch 和 computed 都是以 Vue 的依赖追踪机制为基础的,当某一个数据发生变化的时候,

                                    所有依赖这个数据的相关数据,自动发生变化,也就是自动调用相关的函数去实现数据的变动

                                    methods 里面是用来定义函数的,它需要手动调用才能执行。而不像 watch 和 computed 那样,

                                    “自动执行”预先定义的函数,相比于 watch / compute;methods 不处理数据逻辑关系,只提供可调用的函数,类似储存函数的一个库。

                                  • 从性质上

                                    methods里面定义的是函数,你显然需要像"fuc()"这样去调用它(假设函数为fuc)。

                                    computed是计算属性,事实上和和data对象里的数据属性是同一类的(使用上)。

                                    watch:类似于监听机制+事件机制,回调函数自动调用。

                                    15.$route 和 $router 的区别

                                    router是VueRouter的一个对象,通过Vue.use(VueRouter)和VueRouter构造函数得到一个router的实例对象,这个对象中是一个全局的对象,包含了所有的路由包含了许多关键的对象和属性。例如history对象

                                    route是一个跳转的路由对象,每一个路由都会有一个route对象,是一个局部的对象,可以获取对应的name,path,params,query等

                                    16.v-model的使用

                                    表单控件在实际开发中是非常常见的,特别是对于用户信息的提交,需要大量的表单

                                    Vue中使用v-model指令来实现表单元素和数据的双向绑定

                                    • 案例的解析:

                                      • 当我们在输入框输入内容时
                                      • 因为input中v-model绑定了message,所以会实时将输出的呢容传递给message,message发生改变。
                                      • 当message发生改变时,因为上面我们使用Mustache语法,将message的值参入到DOMZ中,所以DOM会发生相应的变化
                                      • 所以通过v-model实现了双向绑定

                                        17.v-on可以监听多个方法吗

                                        可以

                                         
微信扫一扫加客服

微信扫一扫加客服

点击启动AI问答
Draggable Icon