Vue面试题

持续整合更新中......

1、什么是MVVM
     MVVM是前端的概念,把前端的每一个页面都分层了3个部分:
           Model模型:代表真实状态内容的领域模型(面向对象),或指代表内容的数据访问层(以数据为中心);是通过调用Ajax从服务器端获取回来的;Javascript对象。泛指后端进行的各种业务逻辑处理和数据操控,对于前端来说就是后端提供的 api 接口。
           View视图:用户在屏幕上看到的结构、布局和外观(UI);就是前端的HTML结构,专门用来呈现数据给用户的;DOM
           ViewModel视图模型:是暴露公共属性和命令的视图的抽象;帮助自动渲染前端的页面;观察者,调度者,起到监听数据的作用,实现了数据的双向绑定
     MVVM没有MVC模式的控制器,也没有MVP模式的presenter,有的是一个绑定器。在视图模型中,绑定器在视图和数据绑定器之间进行通信;视图和模型是不能直接通信。实现了双向绑定。
     优点:
     a、低耦合:View可以独立于Model变化和修改,一个ViewModel可以绑定到不同的View上。当View变化的时候Model可以不变,当Model变化的时候View也可以不变。
     b、可重用性:可以把一些视图逻辑放在一个ViewModel里面,让很多View重用这段视图逻辑。
     c、独立开发:开发人员可以专注于业务逻辑和数据的开发,减少了DOM操作,设计人员可以专注于页面的设计。
     d、实现的是业务逻辑组件的重用
     e、通过数据来显示视图层而不是节点操作
     f、主要解决了MVC中大量的dom操作使页面渲染性能降低,加载速度变慢,影响用户体验

2、什么是MVC
     MVC是后端的开发思想,基于分层的目的,让彼此的职责分开,有3层:
           Model模型:表示应用程序核心(如数据库);通常模型对象负责在数据库中存取数据
           View视图:显示效果(HTML页面);通常视图是依据模型数据创建的
           Controller控制器:处理输入(业务逻辑);通常控制器负责从视图读取数据,控制用户输入,并向模型发送数据
     MVC是单向通信,也就是View跟Model,必须通过Controller来承上启下。
     优点:低耦合、重用性高、生命周期成本低、部署快、可维护性高、有利于软件工程化管理

3、为什么组件中的data是一个函数
     组件的data写成一个函数,数据以函数返回值形式定义,类似于给每个组件实例创建一个私有的数据空间,让各个组件实例维护各自的数据。而单纯的写成对象形式,就使得所有组件实例共用了一份data,就会造成一个变了全都会变的结果(作用域没有隔离)。可以维护一份被返回对象的独立的拷贝,组件实例之间的 data 属性值不会互相影响。而 new Vue 的实例,是不会被复用的
     不共享,私有的,独立的。

4、Vue组件通讯有哪些方式
     a、props和$emit:父组件向子组件传递数据是通过props传递的,子组件传递给父组件是通过$emit触发事件来做到的。
     b、$parent和$children:获取单签组件的父组件和当前组件的子组件。
     c、$attrs和$listeners A->B->C
     d、provide和inject:父组件中通过 provide 来提供变量,然后在子组件中通过 inject 来注入变量,常用来写组件库。
     e、$refs获取组件实列
     f、envetBus($emit / $on): 兄弟组件数据传递,这种情况下可以使用事件总线的方式。这种方法通过一个空的 Vue 实例作为中央事件总线(事件中心),用它来触发事件和监听事件,从而实现任何组件间的通信,包括父子、隔代、兄弟组件
     g、vuex 状态管理

5、Vue的生命周期
     Vue 实例有一个完整的生命周期,也就是从开始创建、初始化数据、编译模版、挂载 Dom -> 渲染、更新 -> 渲染、卸载等一系列过程,我们称这是 Vue 的生命周期。
     钩子函数:
         beforeCreate:在实例初始化之后,数据观测(data observe)和 event/watcher 事件配置之前被调用(组件实例被创建之初,组件的属性生效之前)。在当前阶段 data、methods、computed 以及 watch 上的数据和方法都不能被访问。
         created:实例已经创建完成之后被调用(组件实例已经完全创建,属性也绑定,但真实 dom 还没有生成,$el 还不可用)。在这一步,实例已经完成以下的配置:数据观测(data observe ),属性和方法的运算,watch/event 事件回调。这里没有 $el,如果非要想与 DOM 进行交互,可以通过vm.$nextTick 来访问 DOM。
         beforeMount:在挂载开始之前被调用,相关的 render 函数首次被调用。
         mounted:在挂载完成后发生,在当前阶段,真实的 Dom 挂载完毕,数据完成双向绑定,可以访问到 Dom节点,el 被新创建的 vm.$el 替换。
         beforeUpdate:数据更新之前调用,发生在虚拟 DOM 重新渲染和打补丁(patch)之前。可以在这个钩子中进一步地更改状态,这不会触发附加的重渲染过程。(数据修改页面未修改)
         updated:发生在更新完成之后,当前阶段组件 Dom 已经完成更新。要注意的是避免在此期间更新数据,因为这个可能导致无限循环的更新,该钩子在服务器渲染期间不被调用。
         activited:keep-alive 专属,组件被激活时调用
         deactivated:keep-alive 专属,组件被销毁时调用
         beforeDestroy:实例销毁之前调用。在这一步,实例仍然完全可用。我们可以在这时进行 善后收尾工作,比如清除定时器。
         destroyed:Vue实例销毁后调用。调用后,Vue实例指示的东西都会解除绑定,所有的事件监听器会被移除,左右的子实例也会被销毁,该钩子在服务器端渲染不被调用。

6、Vue的异步请求在哪一步发起
     可以在钩子函数 created、beforeMount、mounted 中进行异步请求,因为在这三个钩子函数中,data已经创建,可以将服务器端返回的数据进行赋值。
     a、如果异步请求不需要依赖 DOM,推荐在 created 钩子函数中调用异步请求,优点是能更快获取到服务端数据,减少页面loading时间
     b、如果依赖DOM元素,需要再mounted里面进行请求
     c、ssr 不支持 beforeMount 、mounted 钩子函数,所以放在 created 中有助于一致性

7、v-if和v-show的区别
     v-if:在编译过程中会被转化成三元表达式,条件不满足时不渲染此节点。元素销毁和重建,控制显示隐藏。适用于在运行时很少改变条件,不需要频繁切换条件的场景。它会确保在切换过程中条件块内的事件监听器和子组件适当地被销毁和重建,如果频繁切换条件,比较消耗性能;也是惰性的:如果在初始渲染时条件为假,则什么也不做——直到条件第一次变为真时,才会开始渲染条件块。
     v-show:会被编译成指令,条件不满足时控制样式将此节点隐藏(display:none),css样式控制,不管初始条件是什么,元素总是会被渲染。适用于需要非常频繁切换条件的场景。

8、display:none 、 visibility:hidden 和 opacity:0 之间的区别
     共同点都是隐藏。
     不同点:
         a、是否占据空间
              display:none,隐藏之后不占位置;visibility:hidden、opacity:0,隐藏后任然占据位置。
         b、子元素是否继承
              display:none --- 不会被子元素继承,父元素都不存在了,子元素也不会显示出来
              visibility:hidden --- 会被子元素继承,通过设置子元素 visibility:visible 来显示子元素
              opacity:0 --- 会被子元素继承,但是不能设置子元素 opacity:0 来先重新显示
          c、事件绑定
              display:none 的元素都已经不存在了,因此无法触发他绑定的事件
              visibility:hidden 不会触发他上面绑定的事件
              opacity:0 元素上面绑定的事件时可以触发的
          d、过度动画
              transition对于display和visibility是无效的,但对于opacity是有效的

9、Vue的单项数据流
     数据总是从父组件传到子组件,子组件没有权利修改父组件传过来的数据,只能请求父组件对原始数据进行修改。所有的 prop 都使得其父子 prop 之间形成了一个单向下行绑定:父级 prop 的更新会向下流动到子组件中,但是反过来则不行。每次父级组件发生更新时,子组件中所有的 prop 都将会刷新为最新的值。

10、computed和watch的区别和应用场景
     computed:计算属性,依赖其它属性计算值,并且 computed 的值有缓存(可用于数值计算,避免每次获取值时,都要重新计算),只有当计算值变化才会返回内容(只有它依赖的属性值发生改变,下一次获取 computed 的值时才会重新计算 computed 的值),它可以设置getter和setter。一般用在模板渲染中,某个值是依赖其它响应对象甚至是计算属性而来。
     watch:监听到值的变化就会执行回调,适用于观测某个值的变化去完成一段复杂的业务逻辑。能够执行异步或开销较大的操作。

11、v-if和v-for能不能一起使用
     永远不要把 v-if 和 v-for 同时用在同一个元素(标签)上,因为解析时先解析v-for在解析v-if,会带来性能方面的浪费,每次渲染都会先循环再进行条件判断。
     解决措施:
        a、外层嵌套template,在外部进行v-if,在内部进行v-for
             <template v-if="isShow">
                   <p v-for="item in items">
             </template>
        b、如果条件出现在循环内部,可通过计算属性提前过滤掉数据

12、Vue2响应式数据的原理
     数据劫持+观察者模式
     Vue2.x采用数据劫持结合观察者模式的方式,通过 Object.defineProperty 来劫持各个属性的 setter、getter ,在 数据变动时发布消息给订阅者,触发相应的监听回调。
     a、Object.defineProperty进行数据劫持
     b、使用getter收集依赖,setter通知watcher派发更新
     c、watcher发布订阅模式

13、Vue如何检测数组变化
     重写数组的原型方法。
     Vue2中实现检测数组变化的方法,是将数组的常用方法进行了重写,将 data 中的数组进行了原型链重写 ,指向了自己定义的数组原型方法。这样当调用数组 api 时,可以通知依赖更新 。如果数组中包含着引用类型,会对数组中的引用类型 再次递归遍历进行监控 。这样就实现了监测数组变化。
     有两种情况无法检测到数组的变化:
                a、当利用索引直接设置一个数组项时,例如 vm.items[indexOfItem] = newValue
             解决措施:
                    // vm.$set,Vue.set的一个别名
                    vm.$set(vm.items, indexOfItem, newValue)
                    或vm.items.splice(indexOfItem, 1, newValue)
        b、当修改数组的长度时,例如 vm.items.length = newLength
             解决措施:
                    // Array.prototype.splice
                    vm.items.splice(newLength)

14、Vue的父子组件生命周期钩子函数执行顺序
       加载渲染过程
           父 beforeCreate -> 父 created -> 父 beforeMount -> 子 beforeCreate -> 子 created-> 子 beforeMount -> 子 mounted -> 父 mounted
       子组件更新过程
           父 beforeUpdate -> 子 beforeUpdate -> 子 updated -> 父 updated
       父组件更新过程
           父 beforeUpdate -> 父 updated
      销毁过程 
           父 beforeDestroy -> 子 beforeDestroy -> 子 destroyed -> 父 destroyed
      总结: 父组件先开始,子组件先结束

15、v-model双向绑定的原理
      语法糖 。v-model 在内部为不同的输入元素使用不同的属性并抛出不同的事件,可以通过 model 属性的 prop 和 event 属性来进行自定义。在自定义组件中,v-model 默认会利用名为 value 的 prop 和名为 input 的事件。
       Vue 主要通过以下 4 个步骤来实现数据双向绑定的:
         a、实现一个监听器 Observer:对数据对象进行遍历,包括子属性对象的属性,利用 Object.defineProperty() 对属性都加上 setter 和 getter。这样的话,给这个对象的某个值赋值,就会触发 setter,那么就能监听到了数据变化。
         b、实现一个解析器 Compile:解析 Vue 模板指令,将模板中的变量都替换成数据,然后初始化渲染页面视图,并将每个指令对应的节点绑定更新函数,添加监听数据的订阅者,一旦数据有变动,收到通知,调用更新函数进行数据更新。
         c、实现一个订阅者 Watcher:Watcher 订阅者是 Observer 和 Compile 之间通信的桥梁 ,主要的任务是订阅 Observer 中的属性值变化的消息,当收到属性值变化的消息时,触发解析器 Compile 中对应的更新函数。
         d、实现一个订阅器 Dep:订阅器采用 发布-订阅 设计模式,用来收集订阅者 Watcher,对监听器 Observer 和 订阅者 Watcher 进行统一管理。

16、Vue3响应式数据原理
      Object.defineProperty 无法监控到数组下标的变化,导致通过数组下标添加元素,不能实时响应;Object.defineProperty 只能劫持对象的属性,从而需要对每个对象,每个属性进行遍历,如果属性值是对象,还需要深度遍历。 Proxy代理可以劫持整个对象,并返回一个新的对象 。
      Proxy可以代理对象、数组、动态添加的属性。
      Proxy 只会代理对象的第一层,解决办法:判断当前 Reflect.get 的返回值是否为 Object,如果是则再通过 reactive 方法做代理, 这样就实现了深度观测。
      监测数组的时候可能触发多次 get/set,防止多次触发的措施:可以判断 key 是否为当前被代理对象 target 自身属性,也可以判断旧值与新值是否相等,只有满足以上两个条件之一时,才有可能执行trigger。

17、Vue2和Vue3渲染器的diff算法
     diff算法的过程:
        a、同级比较,再比较子节点
        b、先判断一方有子节点一方没有子节点的情况(如果新的 children 没有子节点,将旧的子节点移除)
        c、比较都有子节点的情况(核心 diff)
        d、递归比较子节点
     Vue2 的核心 Diff 算法采用了双端比较的算法 ,同时从新旧 children 的两端开始进行比较, 借助 key 值找到可复用的节点,再进行相关操作。
     Vue3 借鉴了 ivi 算法和 inferno 算法

18、hash模式和history模式的实现原理
     hash模式:
       URL 中 hash 值只是客户端的一种状态,hash 值的变化,不会导致浏览器向服务器发出请求,浏览器不发出请求,就不会刷新页面;hash 虽然出现在 URL 中,但不会被包含在 HTTP 请求中,对后端完全没有影响,因此改变 hash 不会重新加载页面。可以使用 hashchange 事件来监听 hash 值的变化,从而对页面进行跳转(渲染)。每一次改变 hash (window.location.hash) ,都会在浏览器的访问历史中增加一个记录,能通过浏览器的回退、前进按钮控制hash 的切换, 利用hash 的以上特点,就可以实现前端路由 “ 更新视图但不重新请求页面 ” 的功能了。
     history模式:
       利用 HTML5 History Interface 中新增的 pushState()(新增一个历史记录) 和 replaceState()(直接替换当前的历史记录) 方法,应用于浏览器的历史记录站,当调用他们修改浏览器历史记录栈后,虽然当前 URL 改变了,但浏览器不会刷新页面,这就为单页面应用前端路由“ 更新视图但不重新请求页面 ” 提供了基础。可以使用 popstate 事件来监听 url 的变化,从而对页面进行跳转(渲染)。
     区别:
        a、首先是在 URL 的展示上,hash 模式有“#”,history 模式没有
        b、刷新页面时,hash 模式可以正常加载到 hash 值对应的页面,而 history 没有处理的话,会返回404,一般需要后端将所有页面都配置重定向到首页路由
        c、在兼容性上,hash 可以支持低版本浏览器和 IE

19、vue-router路由钩子函数和执行顺序
      钩子函数种类有:全局守卫、路由守卫、组件守卫。
      完整的导航解析流程:
         1 、导航被触发。
         2 、在失活的组件里调用 beforeRouterLeave 守卫。
         3 、调用全局的 beforeEach 守卫。
         4 、在重用的组件调用 beforeRouterUpdate 守卫( 2.2+ )。
         5 、在路由配置里面 beforeEnter 。
         6 、解析异步路由组件。
         7 、在被激活的组件里调用 beforeRouterEnter 。
         8 、调用全局的 beforeResolve 守卫( 2.5+ )。
         9 、导航被确认。
         10 、调用全局的 afterEach 钩子。
         11 、触发 DOM 更新。
         12 、调用 beforeRouterEnter 守卫中传给 next 的回调函数,创建好的组件实例会作为回调函数的参数传入。

20、vue-router的动态路由
      把某种模式匹配到的所有路由,全都映射到同个组件。
          // 动态路径参数 以冒号开头
         { path: "/user/:id", component: User }
      vue-router 组件复用导致路由参数失效的解决方案:
         a、通过 watch 监听路由参数再发请求
         b、用 :key 来阻止复用:router-view :key="$route.fullPath"

21、vuex的理解
     vuex 是一个专为 Vue 应用程序开发的状态管理器, 采用集中式存储管理应用的所有组件的状态。每一个 vuex 应用的核心就是 store(仓库)。“store” 基本上就是一个容器,它包含着应用中大部分的状态 (state)。用于开发vue的大型应用。
     为什么需要vuex:由于组件只维护自身的状态(data),组件创建时或者路由切换时,组件会被初始化,从而导致 data 也 随之销毁。

22、Vuex页面刷新数据丢失怎么解决
      需要做 vuex 数据持久化 ,一般使用本地储存的方案来保存数据,可以自己设计存储方案,也可以使用第三方插件(vuex-persist)。

23、Vue中使用到的设计模式
      a、发布订阅模式:vue事件机制
      b、观察者模式:响应式数原理
      c、单例模式:整个程序有且仅有一个实例
      d、工厂模式:传入参数即可创建实例
      e、装饰器模式:@装饰器的用法
      f、策略模式:策略模式指对象有某个行为,但是在不同的场景中,该行为有不同的实现方案,比如选项的合并策略

24、Vue性能优化
      a、服务端渲染SSR、预渲染
      b、对象层级不要过深,否则性能就会差
      c、不需要响应式的数据不要放在 data 中(可以使用 Object.freeze() 冻结数据)
      d、v-if 和 v-show 区分使用场景
      e、v-for 遍历必须加 key,key最好是id值,且避免同时使用 v-if
      f、图片懒加载
      g、路由懒加载
      h、适当采用 keep-alive 缓存组件
      i、防抖、节流的运用
      j、computed 和 watch 区分场景使用
      k、大数据列表和表格性能优化 - 虚拟列表 / 虚拟表格
      l、防止内部泄露,组件销毁后把全局变量和时间销毁
      m、异步路由
      n、第三方插件的按需加载

    (1)代码层面的优化
            v-if 和 v-show 区分使用场景
            computed 和 watch 区分使用场景
            v-for 遍历必须为 item 添加 key,且避免同时使用 v-if
           长列表性能优化
           事件的销毁
           图片资源懒加载
           路由懒加载
           第三方插件的按需引入
           优化无限列表性能
           服务端渲染 SSR or 预渲染
    (2)Webpack 层面的优化
           Webpack 对图片进行压缩
           减少 ES6 转为 ES5 的冗余代码
           提取公共代码
           模板预编译
           提取组件的 CSS
           优化 SourceMap
           构建结果输出分析
           Vue 项目的编译优化
    (3)基础的 Web 技术的优化
           开启 gzip 压缩
           浏览器缓存
           CDN 的使用
           使用 Chrome Performance 查找性能瓶颈

25、nextTick的作用
     vue 更新 DOM 是异步更新的,数据变化,DOM 的更新不会马上完成, nextTick的回调是在下次 DOM 更新循环结束之后执行的延迟回调 。
     主要使用微任务(Promise、MutationObserver )和宏任务(setTimeout )

26、keep-alive使用场景和原理
     keep-alive 组件是 vue 的内置组件 ,用于 缓存内部组件 实例。这样做的目的在于,keep-alive 内部的组件切回时, 不用重新创建 组件实例,而直接使用缓存中的实例,一方面能够避免创建组件带来的开销,另一方面可以保留组件的状态 。可以使被包含的组件保留状态,避免重新渲染。一般结合路由和动态组件一起使用,用于缓存组件。提供 include 和 exclude 属性,两者都支持字符串或正则表达式, include 表示只有名称匹配的组件会被缓存,exclude 表示任何名称匹配的组件都不会被缓存 ,其中 exclude 的优先级比 include 高。
     受keep-alive的影响,其内部所有嵌套的组件都具有两个生命周期钩子函数,分别是activated 和 deactivated,它们分别在组件激活和失活时触发。第一次 activated 触发是在 mounted 之后。

27、Proxy 相比 Object.defineProperty 的优势在哪里
     Object.defineProperty的特点:
          a、只能劫持对象属性的 getter 和 setter 方法;
          b、不支持数组(可以监听数组,不过数组方法无法监听,自己重写),更准确的说是不支持数组的各种 API(所以 Vue 重写了数组方法);
          c、只能遍历对象属性直接修改;
          d、兼容性好。
     Proxy的特点:
          a、直接代理劫持整个对象;有多达 13 种拦截方法;
          b、可以直接监听对象(而非属性)和数组的变化;
          c、Proxy 返回的是一个新对象,我们可以只操作新的对象达到目的。

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

29、Class和Style如何动态绑定
     使用v-bind,结合对象语法或数组语法

30、父组件监听子组件的生命周期
     a、在子组件中通过 $emit 触发父组件的事件
          // Parent.vue
          <Child @mounted="doSomething"/>
          // Child.vue
          mounted() {
             this.$emit("mounted");
          }
      b、在父组件引用子组件时通过 @hook 来监听
           //  Parent.vue
          <Child @hook:mounted="doSomething" ></Child>
           @hook 方法可以监听created、mounted、updated等。

31、Vue的SSR
      SSR大致的意思就是vue在客户端将标签渲染成的整个 html 片段的工作在服务端完成,服务端形成的html 片段直接返回给客户端这个过程就叫做服务端渲染。
      Vue.js 是构建客户端应用程序的框架。默认情况下,可以在浏览器中输出 Vue 组件,进行生成 DOM 和操作 DOM。然而,也可以将同一个组件渲染为服务端的 HTML 字符串,将它们直接发送到浏览器,最后将这些静态标记"激活"为客户端上完全可交互的应用程序。
      服务端渲染SSR的优缺点:
      优点:
          a、更好的SEO:SPA 页面的内容是通过 Ajax 获取,而 SSR 是直接由服务端返回已经渲染好的页面(数据已经包含在页面中);
          b、更快的内容到达时间(首屏加载更快):SPA 会等待所有 Vue 编译后的 js 文件都下载完成后,才开始进行页面的渲染,文件下载等需要一定的时间等,所以首屏渲染需要一定的时间;SSR 直接由服务端渲染好页面直接返回显示,无需等待下载 js 文件及再去渲染等,所以 SSR 有更快的内容到达时间。
      缺点:
          a、更多的开发条件限制:服务端渲染只支持 beforCreate 和 created 两个钩子函数;服务端渲染应用程序,需要处于 Node.js server 运行环境;
          b、更多的服务器负载:在 Node.js 中渲染完整的应用程序,显然会比仅仅提供静态文件的 server 更加大量占用CPU 资源。

32、vue-router路由模式有几种
      a、hash:使用 URL hash 值来作路由;支持所有浏览器,包括不支持 HTML5 History Api 的浏览器
      b、history:依赖 HTML5 History API 和服务器配置
      c、abstract:支持所有 JavaScript 运行环境,如 Node.js 服务器端。如果发现没有浏览器的 API,路由会自动强制进入这个模式
        
33、虚拟BOM的优缺点
      优点:
          a、保证性能下限:框架的虚拟 DOM 需要适配任何上层 API 可能产生的操作,它的一些 DOM 操作的实现必须是普适的,所以它的性能并不是最优的;但是比起粗暴的 DOM 操作性能要好很多,因此框架的虚拟 DOM 至少可以保证在你不需要手动优化的情况下,依然可以提供还不错的性能,即保证性能的下限;
          b、无需手动操作 DOM:不再需要手动去操作 DOM,只需要写好 View-Model 的代码逻辑,框架会根据虚拟 DOM 和 数据双向绑定,帮我们以可预期的方式更新视图,极大提高我们的开发效率;
          c、跨平台:虚拟 DOM 本质上是 JavaScript 对象,而 DOM 与平台强相关,相比之下虚拟 DOM 可以进行更方便地跨平台操作,例如服务器渲染、weex 开发等等。
       缺点:
          a、无法进行极致优化:虽然虚拟 DOM + 合理的优化,足以应对绝大部分应用的性能需求,但在一些性能要求极高的应用中虚拟 DOM 无法进行针对性的极致优化。

33、虚拟BOM的实现原理
      a、用 JavaScript 对象模拟真实 DOM 树,对真实 DOM 进行抽象;
      b、diff 算法 — 比较两棵虚拟 DOM 树的差异;
      c、pach 算法 — 将两个虚拟 DOM 对象的差异应用到真正的 DOM 树。

34、Vue与Layui的区别
      a、设计理念不同:Layui是一个轻量级的模块化UI框架,旨在提供简单易用的UI组件和丰富的交互体验,而Vue则是一个更加强大和灵活的框架,它是一套用于构建用户界面的渐进式框架,可以轻松地构建大型的单页应用程序。Layui是一款基于jQuery的开源模块化前端UI框架,主要用于快速搭建前端页面,提高前端开发效率。Vue是一款轻量级、渐进式JavaScript框架,用于构建可复用的Web组件。
      b、使用方式不同:Layui采用的是静态HTML页面的开发方式,需要在HTML页面中引用Layui的样式文件和脚本文件,通过给DOM元素添加class来调用Layui的组件。而Vue则采用的是组件化开发方式,它将应用程序划分为多个独立的组件,每个组件都有自己的状态和行为,通过组合这些组件来构建应用程序。
      c、数据绑定不同:Vue提供了双向数据绑定的能力,即当数据模型改变时,视图会自动更新,而Layui则没有提供这种能力,需要手动更新视图。
      d、生态系统不同:Vue的生态系统非常丰富,拥有大量的第三方库和插件,可以轻松地扩展其功能,而Layui的生态系统相对较小,但也有一些常用的插件可供选择。
      e、社区支持不同:Vue拥有庞大的社区支持,有大量的教程、文档和问答社区,而Layui的社区相对较小,文档和教程相对较少。
      f、应用场景不同:Layui主要面向后台管理系统和企业管理系统等中后台产品,强调简洁、易用和高效,提供了很多常用的UI组件和工具,例如表格、表单、树形菜单、弹窗等,方便开发人员快速搭建页面。Vue则更加注重组件化开发,可以更好地实现页面的复用和模块化,适用于开发各种类型的Web应用。

35、watch 和 watchEffect 区别
     a、watch 和 watchEffect 都能监听响应式数据的变化,不同的是它们监听数据变化的方式不同。
     b、watch 会明确监听某一个响应数据,而 watchEffect 则是隐式的监听回调函数中响应数据。
     c、watch 在响应数据初始化时是不会执行回调函数的,watchEffect 在响应数据初始化时就会立即执行回调函数。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值