Vue面试题,背就完事了

2024-03-19 13:36

本文主要是介绍Vue面试题,背就完事了,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1.vue的生命周期有哪些及每个生命周期做了什么?

Vue.js 的生命周期可以分为以下几个核心阶段,每个阶段都伴随着特定的钩子函数(生命周期钩子)来执行相应的操作:

  1. 创建阶段:

    • beforeCreate:实例被创建后、数据观测和事件配置之前调用。此时,组件的属性如datamethodscomputed等还不可见。
    • created:完成了实例的初始化,数据观测设置完毕,但DOM还未生成。在此阶段,可以进行一些依赖于dataprops的初始化工作,例如调用API获取数据。
  2. 挂载阶段:

    • beforeMount:在挂载开始之前调用。这时模板编译已完成,el选项指定的元素已替换为render函数的内容,但是尚未插入文档流中。
    • mounted:完成挂载,即组件的DOM元素已被挂载到父组件中,并可以在DOM树上进行查询,但可能还有异步更新未完成。这个钩子常用于在组件加载完成后执行DOM相关的操作,如添加第三方库、访问DOM节点或触发初始计算。
  3. 更新阶段:

    • beforeUpdate:数据发生变化时调用,此时变化的数据已经合并到了虚拟DOM中,但是在视图重新渲染前调用。
    • updated:完成对虚拟DOM的重新渲染和打补丁之后调用。此时组件DOM已经更新,可以在这里执行依赖于DOM状态的操作。然而,不建议在这个钩子中频繁进行DOM操作,因为它会执行多次且每次都会导致重渲染。
  4. 销毁阶段:

    • beforeDestroy:实例销毁之前调用,此时实例仍完全可用,但即将解绑所有指令与事件监听器,可以在这时进行清理工作,比如解除订阅、定时器清除等。
    • destroyed:实例已经被销毁,所有的绑定关系都被解除了,DOM元素也从页面中移除,此钩子函数主要用于资源清理工作。

除此之外,Vue 2.x 还有一些其他生命周期钩子,但在 Vue 3.x 中有所改变:

  • activateddeactivated(仅在 Vue 2.x 的 <keep-alive> 缓存组件中使用,对应组件激活与停用的状态)
  • Vue 3.x 引入了新的生命周期钩子,如 onBeforeMountonMountedonBeforeUpdateonUpdatedonBeforeUnmountonUnmountedonErrorCaptured 等,这些钩子提供了更细粒度的控制和更好的可组合性。

总之,Vue 的生命周期钩子让开发者能够在组件的不同阶段执行自定义逻辑,从而更好地管理组件的状态和行为。

2.vue响应式原理是什么? vue3的响应式有何不同

Vue.js 的响应式原理主要是为了实现数据变化时自动更新视图。在 Vue 2.x 和 Vue 3.x 中,虽然目标相同,但实现方式有所差异。

Vue 2.x 响应式原理:

Vue 2.x 使用了 Object.defineProperty() 这个 JavaScript 原生 API 来实现数据的响应式。当创建一个 Vue 实例时,Vue 会遍历 data 对象的所有属性,并使用 defineProperty 将它们转换为 getter 和 setter。getter 负责返回属性值,setter 在值发生改变时触发视图更新。每个组件实例都有一个观察者(Observer)对象负责监视数据变化,同时依赖收集系统(Dep)和订阅者(Watcher)协同工作,当数据变化时通知相关联的 Watcher 执行更新函数,从而引发视图重渲染。

Vue 3.x 响应式原理:

Vue 3.x 则基于 ES6 的 Proxy 对象实现了更高级别的响应式系统。Proxy 可以代理整个对象而非单一属性,提供了一个统一的入口来拦截对象的各种操作,包括但不限于读取、赋值、删除属性等。Vue 3.x 创建了一个 Reactive 函数,它接收一个普通对象并返回一个代理过的响应式对象。相比于 Vue 2.x,Vue 3.x 的响应式系统具有以下优势:

  • 更全面的响应式:Vue 3.x 可以直接对数组方法进行拦截,无需额外处理。
  • 深度监听:Proxy 可以递归地代理嵌套对象,无需手动调用 $set$watch
  • 性能优化:通过跟踪依赖关系,只更新受影响的部分,而非全局重新渲染。
  • 易于维护和扩展:Proxy 提供了一种更简洁且功能更强大的API,简化了内部逻辑。

Vue 3.x 还引入了 Composition API,其中的 refreactive 是创建响应式变量的基础工具。另外,它还采用了一种新的副作用调度机制,用 effect 替代了传统的 Watcher,用于收集和执行副作用函数,如计算属性或DOM更新等。这些改进让开发者在编写代码时有更高的灵活性和更好的性能控制。

3.Vue3和Vue2的区别

Vue3 和 Vue2 在多个方面有显著区别,以下是主要的不同点:

  1. 响应式系统

    • Vue 2.x 使用了 Object.defineProperty 来实现数据的响应式,只能递归地监听对象属性变化,对于数组需要进行特殊处理。
    • Vue 3.x 则采用了 ES6 的 Proxy 对象来创建响应式代理,它提供了更全面、更深度的监听能力,包括对整个对象及其嵌套属性以及数组的所有操作。
  2. API 设计

    • Vue 2.x 主要使用选项式 API(Options API),将组件相关的配置项如 data、methods、computed、watch 等分门别类放置在各自独立的选项中。
    • Vue 3.x 引入了 Composition API,允许开发者以函数式编程的方式组织逻辑,可以将相关联的数据和逻辑组合在一起。同时保留了 Options API 供开发者选择。
  3. 生命周期钩子

    • Vue 2.x 提供了一系列生命周期钩子函数,例如 createdmountedupdated 等。
    • Vue 3.x 改进了生命周期钩子,一些钩子名称上添加了 “on” 前缀,例如 beforeCreate 变为 beforeCreateOn(实际命名是 onBeforeCreate),同时也新增了 setup 钩子作为新的入口点,用于替代之前的部分生命周期钩子,并在此处执行响应式的初始化设置。
  4. 模板语法改进

    • Vue 3.x 支持 Fragment(碎片),允许组件模板拥有多个根元素。
    • Vue 3.x 中 v-ifv-for 的优先级问题得到了解决,现在如果在同一元素上同时使用这两个指令,会按照语义正确解析并可能报错,建议分开使用或者通过 <template> 标签包裹。
  5. 新特性

    • Vue 3.x 新增了 Suspense 组件用于异步组件加载时的占位和回退内容渲染。
    • Teleport 组件使得开发者能够将部分 DOM 元素渲染到指定的目标容器之外的位置。
    • 提供了更完善的 TypeScript 类型支持,增强了大型项目中的可维护性和开发体验。
  6. 性能优化

    • Vue 3.x 进行了大量的性能优化,包括更快的虚拟DOM diff算法、更高效的响应式系统等,从而提高了应用的整体性能。
  7. 创建应用实例

    • Vue 2.x 中创建应用实例使用 new Vue() 方法。
    • Vue 3.x 中引入了 createApp 函数,通过 const app = createApp(App) 创建应用实例后,再通过 app.mount('#app') 完成挂载。

总结来说,Vue 3.x 在保持与 Vue 2.x 相似易用性的同时,着重于提高代码复用性、灵活性以及底层性能,并且提供了更多现代前端开发所需的高级功能。

4.谈一谈对MWM的理解?

在Vue.js中并没有直接相关的“MWM”概念。不过,从上下文推测,可能您想询问的是MVVM模式,或者是Vue.js中的某些组件或概念的误解。

  • MVVM
    在Vue.js中,MVM可能是MVVM(Model-View-ViewModel)架构模式的一个误写。Vue是基于MVVM设计思想构建的前端框架,其中:

    • M (Model):代表应用的数据模型,包含业务逻辑和数据。
    • V (View):视图层,负责将数据以用户界面的形式展示出来。
    • VM (ViewModel):视图模型,它是连接Model和View的桥梁,它包含了视图状态及可观察的属性,并且能够监听Model的变化并自动更新View,同时也能处理View层的用户交互事件并更新Model。
  • 其他可能性
    如果“MWM”在Vue.js环境中没有特定指代,则上述关于MWM其他含义的信息同样不适用于Vue.js上下文。例如,“Most Worshipful Master”、“Married White Male”、“Metawavemusic”、“Motif Window Manager”等与Vue.js无关。

总之,在Vue.js领域内讨论"MWM"时,若非特别指定,通常不会指向任何具体的概念或特性,而应当是与MVVM模式相关联的ViewModel部分。

5.在Vue2.x中如何检测数组的变化?

在Vue 2.x中,Vue.js通过重写数组的7个变异方法来检测数组的变化。这些变异方法会触发视图更新,当调用它们时,Vue能够知道数组内部发生了变化,并相应地更新依赖于该数组的任何组件。

这7个变异方法包括:

  1. push()
  2. pop()
  3. shift()
  4. unshift()
  5. splice()
  6. sort()
  7. reverse()

当你直接使用这些方法修改数组时,Vue可以追踪到这些变化并自动更新视图。例如:

data() {return {items: [1, 2, 3]}
},
methods: {addItem() {this.items.push(4); // 这将触发视图更新},removeFirst() {this.items.shift(); // 视图也会响应这个操作而更新}
}

然而,如果你使用非变异方法(如concat()slice()或者直接赋值索引)来改变数组内容,Vue将无法自动检测到这些变化。在这种情况下,你需要使用Vue提供的工具来确保视图同步:

  • 使用this.$set方法来添加或修改已存在的数组元素。
  • 如果需要替换整个数组,可以设置整个数据属性为一个新的数组,而不是直接修改原数组。

例如:

// 添加新元素到数组内特定位置
this.$set(this.items, index, newValue);// 替换整个数组以确保触发变更通知
this.items = newArray;

注意:Vue 3.x 的响应式系统基于 Proxy,对数组的变化跟踪更为全面和高效,无需特殊处理就能监测到数组的所有变化。但在 Vue 2.x 中,必须遵循上述方式来确保数组变化能被正确检测和更新视图。

6.v-model双向绑定的原理是什么?

Vue.js 中 v-model 双向数据绑定的原理基于 Vue 的响应式系统和事件监听机制。以下是对 v-model 双向绑定工作原理的详细说明:

  1. 数据到视图

    • 当在 Vue 组件中定义一个变量,并使用 v-model 与表单元素(如 input、textarea、select 等)进行绑定时,Vue 会利用其响应式系统来实现数据到视图的绑定。
    • 响应式系统的核心是通过 Object.defineProperty() 方法对组件实例的 data 属性进行观察(observe)。这意味着当给定的变量(例如 message)发生变化时,Vue 能够检测到这个变化并触发相应的更新过程。
    • 对于输入类型的表单元素,Vue 会在渲染过程中将 v-model 绑定的变量值赋给元素的 value 属性。
  2. 视图到数据

    • 为了实现视图到数据的绑定,Vue 在内部为 v-model 提供了语法糖,它实际上监听了绑定元素上的特定事件(通常是 inputchange 事件)。
    • 当用户在输入框内输入内容或者选择其他表单控件选项时,这些操作会触发对应的 DOM 事件。
    • Vue 在处理这些事件时,会读取当前元素的值(比如 event.target.value),然后将其赋值给 v-model 绑定的数据属性,从而实现了从视图到数据的同步。

总结来说,v-model 指令使得表单元素的值可以与 Vue 组件中的数据属性保持同步。无论是通过 JavaScript 修改数据属性还是直接修改表单元素的值,都会触发响应式系统的相应动作,确保数据和视图始终保持一致。具体到不同类型的表单元素,Vue 还会对 v-model 进行一些特殊的适配处理,如对于 checkbox 和 radio,它们绑定的是 checked 属性,而对于 select 则是根据选中的 option 来更新绑定值。

7.vue2.x和vuex3.x渲染器的diff算法分别说一下?

Vue 2.x 和 Vuex 并没有直接关联的渲染器 diff 算法,但我们可以分别讨论 Vue 2.x 的虚拟 DOM diff 算法和 Vuex 在状态管理中的作用以及它如何影响组件渲染。

Vue 2.x 中的 Diff 算法:
Vue 2.x 使用了虚拟 DOM(Virtual DOM)技术,并实现了一套高效的 diff 算法来比较新旧虚拟节点树,以确定最小化的DOM操作。其主要特点和策略包括:

  • 同层级比较:Vue 的 diff 算法首先在同一层级进行节点比较,而非跨层级比较。
  • 移动优化:通过从两端开始比较子节点的方式(双端比较算法),尽可能地复用现有DOM节点,减少不必要的移动操作。
  • 键(key)的作用:Vue 使用 key 来辅助识别哪些元素是同一逻辑单元的不同状态,当有相同的 key 时,Vue会选择移动节点而不是创建新的节点。
  • 时间复杂度优化:尽管在最坏情况下 diff 算法的时间复杂度理论上可能是 O(n^3),但在实际应用中,由于上述优化措施,Vue可以将大部分情况下的性能降至接近 O(n)。

Vuex 3.x 状态管理与渲染器的关系:
Vuex 是 Vue.js 应用程序的状态管理模式+库,它不涉及渲染器或diff算法的具体实现。然而,Vuex 对于组件渲染有着间接的影响:

  1. 集中式状态管理:Vuex 提供了一个全局可访问的状态容器,所有组件都可以读取和修改这个共享状态。当状态改变时,依赖这些状态的组件会收到通知并触发重新渲染。
  2. 响应式数据流:Vuex 内部也利用了 Vue 的响应式系统,当 Vuex store 中的状态发生变更时,Vue 能够检测到这些变化并通过组件的 computed 属性、watchers 或者 Vuex 的 mapState 辅助函数等方式更新相关组件的视图。

所以虽然 Vuex 不直接处理渲染器的 diff 算法,但它确保了状态变化能够正确传播至所有依赖的组件,从而促使这些组件根据新的状态进行有效且高效的重新渲染。

8.vue组件通信方式有哪些及原理

Vue组件通信方式有很多种,下面列举了常见的几种,并简述其原理:

  1. Props和$emit(父子组件通信)

    • Props:父组件通过属性绑定向子组件传递数据。在子组件中,props是可配置的输入项,当父组件的数据发生变化时,会自动更新到使用这些props的子组件中。
    • ** e m i t ∗ ∗ :子组件通过 ‘ t h i s . emit**:子组件通过`this. emit:子组件通过this.emit(‘事件名’, 参数)`触发自定义事件并向父组件发送数据。父组件在其模板中监听这个事件并执行相应的处理函数。
  2. p a r e n t / parent/ parent/children(直接访问)

    • 子组件可以通过this.$parent访问父组件实例,父组件可以通过this.$children访问子组件实例。但这不是推荐的方式,因为直接依赖于组件树结构,不利于代码维护和扩展。
  3. 事件总线/Event Bus(非父子组件通信)

    • 创建一个中央事件总线(通常是空的Vue实例),任何组件都可以在这个总线上触发事件或监听事件,实现跨级、兄弟组件间的通信。
  4. Vuex(状态管理库)

    • Vuex提供了一个中心化的存储仓库,所有组件都可以通过actions修改state,通过getters获取state,从而实现多个组件共享状态和复杂的状态管理。组件通过mapState、mapGetters、mapActions等辅助函数与store进行交互。
  5. provide/inject

    • 父组件可以使用provide方法将数据提供给后代组件,而不论它们之间的距离有多远。后代组件通过inject声明需要从祖先注入哪些属性,这样就可以拿到提供的数据。
  6. ref$refs

    • 使用 ref 属性可以在子组件上注册引用信息,然后在父组件中通过 this.$refs.refName 访问到子组件实例,可以直接调用子组件的方法或者操作子组件的属性。
  7. a t t r s / attrs/ attrs/listeners(适用于隔代组件通信):

    • $attrs包含了父作用域未被识别的特性绑定 (attribute bindings) 将作为对象传递给子组件。而$listeners包含了父作用域中的 (不含 .native 修饰器的) 事件监听器。
  8. Async Components and Slots

    • 异步组件加载过程中可以通过上下文通信,而插槽(Slots)则允许父组件传递内容到子组件内部特定位置,也是一种间接的通信形式。

每种通信方式都是基于Vue.js的响应式系统和组件化设计思想来实现的,确保组件间数据变化能够及时同步并驱动视图更新。

9.Vue的路由实现,hash路由和history路由实现原理说一下

Vue.js 的路由实现主要依赖于 vue-router 库,它提供了两种不同的路由模式:hash 路由和 history 路由。

Hash 路由(Hash Mode)

原理:
在 hash 模式下,URL 中的路由信息是通过 URL 后面的哈希(#)来表示的,例如 http://example.com/#/home。当用户点击链接或执行导航操作时,浏览器只会滚动到页面中对应的锚点(由于 # 在传统意义上用于标识页面内的位置),并不会真正向服务器发起新的HTTP请求。

Vue Router 利用了这个特性,在初始化时监听 window.onhashchange 事件,当哈希值变化时,Vue Router 解析出新的路由,并根据路由匹配相应的组件进行渲染。这样,即使地址栏中的哈希部分改变,页面内容也会发生更新,而不会导致整个页面刷新。

History 路由(History Mode)

原理:
history 模式利用了 HTML5 提供的 History API,具体来说是 pushState()replaceState() 方法,这两个方法允许我们修改浏览器的历史记录栈,从而改变了当前 URL,同时保持页面不刷新。

在 history 模式下,Vue Router 生成的 URL 将不再包含哈希(#),而是像传统的多页面应用那样看起来更自然,例如 http://example.com/home

但是,为了使这种模式下的路由能在没有服务器支持的情况下正常工作,需要对服务端进行配置以处理任何非静态资源的请求。当用户直接访问一个路由对应的URL或者刷新页面时,如果没有正确配置服务器,服务器可能无法找到对应的资源并返回404错误。

Vue Router 在历史模式下会监听浏览器的 popstate 事件,该事件会在用户点击浏览器的前进、后退按钮或者调用 history.pushState()history.replaceState() 后触发,然后Vue Router 根据新的URL进行路由解析与组件渲染。

总结起来,hash路由适用于所有支持哈希锚点的浏览器,无需特殊服务器配置;而history路由提供了更为美观的URL,但需要适当的服务端配合以确保SPA应用在无JavaScript环境下也能正确重定向至入口页面。

10.说一下v-if与v-show的区别

Vue.js 中的 v-ifv-show 都是用来根据条件展示或隐藏DOM元素的指令,但它们在实现方式和性能影响上有所不同:

  1. 渲染机制

    • v-if:它会根据表达式的真假条件进行条件性渲染。当条件为 false 时,Vue 不仅不会渲染对应的元素及其包含的所有内容,而且这些元素也不会被添加到 DOM 中。这意味着如果初始条件为 false,那么相关元素将不会被编译和创建。每次条件改变且变为 true 时,Vue 会重新编译并渲染该元素;反之,条件变为 false 时,则会销毁该元素。
    • v-show:无论条件是否为真,元素总是会被渲染并添加到 DOM 中。它只是简单地通过 CSS 的 display 属性来控制元素的可见性,即当条件为 false 时,设置元素的 displaynone,使其不可见;而条件为 true 时,将其设回 block 或其他合适的默认值,使元素变得可见。
  2. 性能开销

    • v-if:由于其有控制DOM节点存在的特性,所以在切换过程中涉及DOM的创建与销毁,会有较高的切换开销,但在不满足条件时避免了不必要的渲染和内存占用,对于频繁切换且大部分时间不需要显示的场景更为高效。
    • v-show:初始渲染时所有元素都会被编译和插入到DOM中,所以相对而言,首次渲染时的开销更高,因为不论条件如何都会执行一次编译操作。但是,在后续切换显示/隐藏状态时,只涉及到CSS属性的变化,因此相比 v-if 来说切换的速度更快,没有额外的DOM操作成本。
  3. 使用场景建议

    • 当你需要在条件很少改变、或者初始条件就确定不会显示的情况下,以及为了节省资源(如懒加载)时,可以优先考虑使用 v-if
    • 如果元素需要频繁切换显示状态,或者初始状态不确定但以后可能频繁出现显示/隐藏的状态变化,使用 v-show 可能更适合,因为它避免了重复的DOM编译和卸载过程,切换更加流畅迅速。

11.keep-alive的常用属性有哪些及实现原理

Vue 的 <keep-alive> 组件用于缓存组件实例,防止在路由切换或条件渲染时销毁并重新创建组件,从而保持组件的状态和避免重复渲染带来的性能消耗。<keep-alive> 提供了几个常用的属性来控制哪些组件需要被缓存:

  1. include

    • 类型:字符串、正则表达式或一个数组
    • 作用:只有名称匹配 include 指定的组件才会被缓存。可以指定一个组件名或者一组组件名(通过数组)进行精确或模式匹配。
  2. exclude

    • 类型:字符串、正则表达式或一个数组
    • 作用:任何名称匹配 exclude 指定的组件都不会被缓存,即使它们同时匹配了 include 规则。
  3. max(非官方默认支持,可能需要自定义实现):

    • 类型:数字
    • 作用:限制缓存组件的最大数量,当缓存列表中的组件超过这个数目时,最早的缓存项会被移除以腾出空间给新的缓存组件。

实现原理

  • 当 Vue 组件被 <keep-alive> 包裹时,它会在激活/停用状态之间切换,而非每次都被销毁和重新创建。
  • 在组件的生命周期中,会触发两个额外的钩子函数:
    • activated:当组件被从缓存中取出并重新激活时调用。
    • deactivated:当组件离开当前视图但并未被销毁而是放入缓存时调用。

<keep-alive> 内部维护了一个缓存队列,用来存储被缓存的组件实例。当组件被切换出去后,Vue 不会立即调用其 beforeDestroydestroyed 生命周期钩子,而是将其保留在内存中,并执行 deactivated 钩子;当组件再次进入视图时,则直接从缓存中取出并执行 activated 钩子,避免了组件初始化及DOM渲染等开销。

此外,在Vue内部,<keep-alive> 会利用 Vue 的响应式系统对包裹的组件进行跟踪和管理,通过动态调整组件的挂载与卸载状态来实现组件级别的缓存机制。

12. nextTick的作用是什么?他的实现原理是什么?

Vue 中的 nextTick 函数的作用是在下次 DOM 更新循环结束之后执行延迟回调。在 Vue.js 的数据响应式系统中,当数据发生变化时,Vue 会异步更新视图。这意味着尽管数据已经发生了变化,但 DOM 可能还没有立即进行同步更新。

this.$nextTick() 方法允许开发者在数据变化后,DOM 更新完成时执行回调函数,确保在回调内可以访问到更新后的 DOM 结构。这个功能在需要基于新渲染的 DOM 执行某些操作时非常有用,例如获取更新后的元素尺寸、样式或对DOM进行进一步操作等。

实现原理:

Vue 的 nextTick 实现原理依赖于 JavaScript 的事件循环机制。它提供了多种策略来执行回调:

  1. Promise (优先选择)
    在支持 Promise 的浏览器环境中,Vue 会使用原生的 Promise 实现,通过 Promise.resolve().then(callback) 来将回调推入微任务队列,这样在当前任务(包括可能存在的同步任务)完成后,但在下一次事件循环开始前,就会执行这些回调。

  2. MutationObserver
    在不支持 Promise 或者在特定环境下(如 IE 浏览器),Vue 可能会选择 MutationObserver 来观察和监听 DOM 变化,然后在 DOM 改变时执行回调。

  3. setTimeout(f, 0)
    如果以上两种方法都不适用,则会退回到使用 setTimeout(callback, 0) 将回调推入宏任务队列,等待下一轮事件循环时执行。

总的来说,无论采用哪种方式,nextTick 都保证了回调会在 DOM 更新之后执行,从而避免了因 DOM 还未更新完毕而引发的操作异常。

13. 说一下Vue SSR的实现原理

Vue Server-Side Rendering(Vue SSR)是指在服务器端将Vue应用渲染为HTML字符串,然后将这个完整的HTML页面发送给客户端。实现原理主要包括以下几个步骤:

  1. 服务端初始化Vue实例
    在服务器端,通过 vue-server-renderer 包创建一个Vue实例,并为其提供数据、路由信息等上下文。

  2. 组件渲染与虚拟DOM生成
    当用户请求到达服务器时,Vue会根据当前的URL匹配到对应的路由,并开始渲染相应的组件树。组件的模板和逻辑在服务端执行,Vue会递归地将每个组件转换为虚拟DOM(VNode)。

  3. SSR渲染过程
    Vue使用虚拟DOM对组件进行渲染,但在服务端环境下,它会以一种特殊的方式执行:生成实际的HTML字符串而非操作DOM。这个过程中,Vue会遍历整个组件树,逐层计算出每个节点应该呈现的内容,并将其拼接成完整的HTML字符串。

  4. 异步数据预取
    如果存在需要从服务器获取的数据,通常会在SSR渲染前进行异步数据预取,确保首屏加载时包含所需数据。这一步骤可以通过Vue Router的async componentsasyncData方法来完成。

  5. 输出HTML并发送至客户端
    渲染完成后,Vue会返回一个包含完整HTML结构和内嵌JavaScript脚本的字符串。这些脚本主要用于在客户端启动Vue应用并进行客户端渲染的“激活”(hydration)过程,即将静态HTML转化为可交互的SPA(Single Page Application)。

  6. 客户端接管与 hydration
    客户端接收到服务器返回的HTML后,浏览器解析并展示页面内容。接着,Vue.js客户端库启动,它会检测到已经存在的服务器渲染内容,并对其进行 hydration,即把静态HTML转换为动态的、响应式的Vue组件,恢复其在客户端的响应式功能。

  7. 客户端后续交互与路由切换
    一旦hydration完成,客户端就完全接管了应用的状态管理及交互。之后的任何路由切换或状态改变都将在客户端内部处理,无需重新发起HTTP请求进行服务器端渲染。

Vue SSR的主要优势在于改善SEO优化(搜索引擎爬虫可以抓取到初始渲染的内容),同时也能提高首屏加载速度,因为用户不需要等待所有JavaScript加载和执行完毕就能看到基本的页面内容。

14.Vue组件的data为什么必须是函数

Vue.js中,组件的data选项必须是函数的原因是为了确保每个组件实例都拥有独立的数据副本,从而保持数据的独立性和组件的可复用性。以下是具体解释:

  1. 防止共享引用
    data是一个对象时,如果多个组件实例直接共享这个对象,它们将指向内存中的同一地址。这意味着当一个组件修改了数据,所有引用该对象的其他组件也会受到影响,因为它们实际上都在操作同一个对象。

  2. 创建独立状态
    为了让每个组件实例维持自己独有的状态,Vue规定data必须是一个返回对象的函数。每次创建新的组件实例时,Vue都会调用这个函数来获取一个新的数据对象实例。这样,每个组件实例都有自己的数据副本,彼此之间不会相互干扰。

  3. 响应式系统初始化
    Vue通过其响应式系统追踪对数据属性的更改,并自动更新相应的视图。为了正确地为每个组件实例设置独立且可观察的数据属性,Vue需要在组件实例化过程中根据data函数生成一个新的、带有响应式特性的对象。

总结来说,在Vue中将data设计成函数的核心目的就是保证组件内部状态的隔离性和每个组件实例的一致性,避免不同组件实例之间的状态混乱,提高代码的可维护性和程序的健壮性。

15.说一下Vue的computed的实现原理

Vue.js 中的 computed 是一个核心特性,它允许开发者声明计算属性,这些属性的值依赖于其他响应式数据。当依赖的数据发生变化时,计算属性会自动重新计算,并且 Vue 会对结果进行缓存以避免不必要的重复计算。

以下是 Vue 中 computed 实现原理的简要概述:

  1. 初始化阶段

    • 在组件实例化过程中(即调用 new Vue(options) 时),Vue 会在内部调用 _init 方法对组件选项进行初始化。
    • 初始化过程中,Vue 会遍历并处理 computed 对象中的属性,通过 initComputed 函数创建计算属性的 getter 和可选的 setter。
  2. 响应式依赖收集

    • 计算属性的 getter 是一个函数,在首次访问该计算属性或者其依赖项发生改变时被调用。
    • 当执行 getter 时,Vue 的响应式系统会追踪和记录所有读取到的依赖数据属性(也就是 getters 被触发的属性)。
  3. Watcher 创建与管理

    • 每个计算属性都会关联一个特殊的 Watcher 实例,这个 Watcher 监听着计算属性的依赖关系。
    • 当计算属性的依赖发生变化时,对应的 Watcher 就会被调度执行,从而触发计算属性的重新计算。
  4. 缓存机制

    • Vue 为每个计算属性的结果提供了一个缓存机制,这意味着如果计算属性的依赖没有变化,那么下一次获取计算属性时将直接返回缓存的结果,而不是重新执行 getter。
  5. 懒计算(惰性求值)

    • 计算属性是“惰性”求值的,也就是说它们只在真正需要的时候才进行计算。首次访问或相关依赖变化后才会计算,未访问时不会执行任何计算操作。
  6. getter 和 setter

    • computed 可以定义 setter,当外部尝试修改计算属性时,setter 会被调用,从而可以更新相关的依赖数据。

总之,Vue 中的 computed 属性实现的核心在于依赖追踪、响应式系统的 Watcher 结构以及智能的缓存策略,这使得计算属性能够高效地维护和更新视图状态。

16.说一下Vue complier的实现原理是什么样的?

Vue Compiler(编译器)是Vue.js框架中负责将模板字符串转化为可执行的JavaScript代码的关键组件。Vue 2.x和Vue 3.x中的编译器实现原理虽有不同,但都遵循相似的基本流程:

Vue 2.x 编译器实现原理概览:

  1. 解析阶段 (Parser):

    • 使用正则表达式和有限状态机等技术对传入的HTML模板字符串进行词法分析和语法分析,生成抽象语法树(AST)。这个过程中会识别并处理指令、插值表达式、元素属性等。
  2. 优化阶段 (Optimizer):

    • 在生成的AST上标记静态节点,即那些在渲染过程中不会因为数据变化而发生变化的部分。这有助于提高后续虚拟DOM更新时的性能。
  3. 转换阶段 (Transformer):

    • 根据AST对模板进行进一步转换,例如对v-if和v-for等指令进行静态分支消除、循环变量收集等优化操作。
  4. 代码生成阶段 (Code Generator):

    • 最后,根据优化后的AST生成渲染函数代码字符串。这个渲染函数的主要任务是在运行时基于当前的数据模型创建虚拟DOM(VNode),进而与实际DOM进行对比和更新。

Vue 3.x 编译器实现原理概览:

  1. @vue/compiler-sfc

    • Vue 3 中单文件组件(SFC)的编译分为多个部分,包括模板编译、脚本编译、样式编译等。
  2. template compiler

    • 模板编译依然涉及解析、优化和代码生成过程,但使用了更先进的编译工具链,如@vue/compiler-dom库,该库采用Babel作为基础构建工具,提供了更灵活且强大的编译能力。
  3. 解析与生成

    • 使用parse方法解析模板字符串到AST,然后通过generate方法从AST生成渲染函数。
  4. 响应式系统改进

    • Vue 3 的编译器还结合了新的响应式系统 proxy,在编译过程中会为依赖于响应式对象的属性访问添加getter和setter,以实现自动追踪依赖。
  5. Fragment 和 Teleport 等新特性支持

    • Vue 3 编译器还支持Vue 3引入的新特性,比如处理多根元素的Fragment语法以及Teleport(传送门)等。

总之,Vue Compiler的核心目标是将模板转换成高效的JavaScript代码,这些代码在运行时能够依据数据的变化动态更新视图,并确保整个过程具有良好的性能和响应性。

17.Vue与Angular以及React的区别是什么?

Vue、Angular和React是现代前端开发中三个非常流行的JavaScript框架/库,它们在设计理念、架构、学习曲线以及具体实现上各有特点。以下是它们之间的一些主要区别:

  1. 学习曲线与易用性

    • Vue:通常被认为具有最平缓的学习曲线,其API设计简洁且易于理解,文档友好,适合快速上手,尤其对于小型到中型项目。
    • React:学习曲线相对适中,需要熟悉JSX(JavaScript XML)语法和组件化思想,但比Angular更易入门。
    • Angular:学习曲线较陡峭,因为它是一个全面的框架,拥有大量的概念和技术栈,比如依赖注入、模块化、指令系统等。
  2. 架构与生态系统

    • Vue.js:核心库专注于视图层,轻量级,可扩展性强,可以选择性地引入路由、状态管理等库来构建大型应用,生态虽小但增长迅速。
    • React:本身只是一个UI库,用于构建可重用的组件,不包含内置的路由或全局状态管理等功能,开发者需要搭配第三方库如React Router、Redux等构建完整应用,生态庞大且灵活。
    • Angular:作为全功能框架,提供了包括路由、表单处理、HTTP客户端等在内的全套解决方案,适合大型企业级应用,生态较为成熟。
  3. 模板语法与编程模型

    • Vue:使用类似HTML的模板语法,支持指令和插值表达式,同时也支持基于JavaScript的渲染函数。
    • React:采用JSX语法,允许在JavaScript代码中编写近似于HTML的结构,强调组件化开发,并通过props和state进行数据传递。
    • Angular:也采用了模板语言,支持类型安全的模板和指令,同时利用TypeScript增加静态类型检查能力。
  4. 状态管理

    • Vue:官方提供Vuex作为状态管理库,适用于复杂应用中的共享状态管理。
    • React:没有内置的状态管理方案,社区推荐Redux、MobX等工具进行状态管理。
    • Angular:自带RxJS,可用于处理异步操作和状态管理,同时有Angular服务等机制处理组件间通信和共享状态。
  5. 性能与优化

    • Vue和React都采用虚拟DOM和高效的更新算法来确保高效渲染。
    • Angular自从版本2之后,采用了变更检测策略进行优化,同样保证了良好的性能表现。
  6. 社区与资源

    • React由于Facebook的支持和早期普及,在开源社区和商业应用中都有广泛的使用和丰富的资源。
    • Angular作为Google支持的框架,也有庞大的用户群和企业级应用场景。
    • Vue虽然相对较晚出现,但因其易用性和灵活性,近年来在国内外发展迅速,社区活跃度不断提高。

总之,Vue、React和Angular各自具备不同的优势,选择哪一个取决于项目需求、团队技术栈和个人喜好。Vue适合追求简单直观、对性能要求高的场景;React更适合关注可复用组件和大规模应用构建;而Angular则特别适合需要全方位框架支持的企业级项目。

18.说一下watch与computed的区别是什么?以及他们的使用场景分别是什么?

Vue.js 中的 watchcomputed 都是用来响应数据变化并执行相应逻辑的功能,但它们在用途、实现方式和使用场景上有所不同:

Computed(计算属性):

  • 功能与原理:
    Computed 属性基于其依赖的数据进行计算,并且结果会被缓存。只有当计算属性所依赖的其他数据发生变化时,才会重新计算结果。计算属性是通过定义一个返回值的函数来创建的。

  • 特点:

    • 自动追踪依赖关系:Vue会自动追踪计算属性中读取的所有数据源,当这些数据源改变时,会触发计算属性的重新计算。
    • 结果缓存:如果计算属性所依赖的数据没有发生改变,那么直接从缓存中返回之前计算的结果,避免了不必要的重复计算。
    • 只读性:计算属性默认只能被读取,不能直接赋值。
  • 使用场景:

    • 当需要根据多个props或data属性计算出一个新的衍生值时,例如计算总金额(商品价格 * 数量)、过滤/排序列表等。
    • 在模板中频繁使用的复杂表达式,为了性能优化和代码可读性,可以将其封装到计算属性中。

Watch(侦听器):

  • 功能与原理:
    Watch 是用于监听特定数据的变化,并在其变化时执行一个或一组回调函数。它可以监听单个数据属性,也可以监听对象或数组的深度变化。

  • 特点:

    • 手动指定观察点:开发者需要明确指定要监听哪些数据属性的变化。
    • 异步支持:watch 监听器内部可以执行异步操作,而 computed 不支持异步计算。
    • 更多控制选项:比如 deep(深度观察)、immediate(立即执行)等。
  • 使用场景:

    • 当需要对某个数据变化做出额外处理时,如发送API请求更新服务器状态、手动更新DOM、触发副作用等。
    • 对于非简单计算逻辑,或者需要在数据变化后做一系列复杂操作的情况。
    • 需要监听深层次的对象或数组结构变化时,配合 deep 选项使用。

总结来说,computed 适用于那些用来表示组件状态的一部分,并且总是基于其他状态计算得出的场景,它提供了高性能和易于维护的计算结果存储机制。而 watch 则更加灵活,可以用于处理更复杂、自定义的监听逻辑以及数据变更后的附加动作。

19.说一下你知道的vue修饰符都有哪些?

Vue.js 提供了一系列修饰符来增强指令的功能,以下是一些常见的 Vue 修饰符:

  1. 事件修饰符:

    • .stop:阻止事件冒泡(event propagation),等同于调用 event.stopPropagation()
    • .prevent:阻止默认行为(default behavior),等同于调用 event.preventDefault()
    • .capture:添加事件监听器时使用事件捕获模式。
    • .once:让事件只触发一次。
    • .self:仅当事件在元素自身(而非子元素)触发时才触发回调函数。
    • . passive:告诉浏览器你不想阻止对此事件的默认行为。
  2. 表单修饰符:

    • .lazy:用于 v-model 指令,使得输入框的内容在失去焦点时而不是每次输入时更新绑定值。
    • .number:确保 v-model 绑定值为数字类型。
    • .trim:自动过滤用户输入内容的首尾空白字符。
  3. 按键修饰符:

    • .enter, .tab, .delete, .esc, .space 等:用于键盘事件,比如在 v-on:keyup.enter 中指定只有按下回车键时才触发事件处理器。
  4. 系统修饰键组合:

    • .ctrl, .alt, .shift, .meta(即Windows/Linux上的Ctrl或MacOS上的Command键):可以与其它按键修饰符结合,例如 @keyup.ctrl.enter
  5. 其他修饰符:

    • .exact(Vue 3.x 新增):用于精确匹配一组按键修饰符组合,防止意外触发。

需要注意的是,不同的Vue版本可能会有一些差异。以上提到的修饰符涵盖了大部分常见场景,但并不是所有修饰符都适用于每一个指令,且随着Vue框架的演进,可能会有新的修饰符被引入或原有的优化和改进。

20.如何实现vue项目中的性能优化?

Vue.js项目性能优化可以从多个层面进行,以下是一些关键的性能优化策略:

  1. 代码拆分与懒加载

    • 使用动态导入(import()vue-routerlazy loading)实现路由级别的按需加载,减少初始加载时的文件大小。
    • 对于大型组件或者第三方库,可以考虑使用异步组件。
  2. 资源优化

    • 使用Webpack等构建工具对CSS和JavaScript进行压缩、合并和Tree Shaking(去除未使用的代码)。
    • 静态资源如图片采用CDN加速,并根据需要选择合适的格式和压缩级别。
    • 使用v-bind:srcsetsizes属性优化图片响应式加载。
  3. Vue实例优化

    • 通过v-ifv-show合理控制组件渲染,避免不必要的计算和DOM操作。
    • 使用key属性在列表渲染中提高重用性,避免不必要的元素重新排序。
    • 注意避免过多的全局状态和深层嵌套组件,减少依赖追踪开销。
  4. Vue响应式系统优化

    • 尽量避免直接修改数组和对象,而是使用Vue提供的变异方法(如$setpushsplice等)或替换整个数据源以触发视图更新。
    • 对于复杂对象结构,使用Object.freeze冻结不可变数据,降低Vue的观测负担。
    • 精简datacomputed中的属性数量,只保留必要的响应式数据。
  5. Vue生命周期钩子优化

    • beforeUpdateupdated钩子中避免执行高耗时或非必要计算。
    • 使用createdmounted而非beforeCreate初始化数据请求。
  6. 缓存计算结果

    • 使用computed属性替代复杂的模板表达式或方法调用,Vue会自动缓存计算结果,只有当依赖发生变化时才会重新计算。
  7. 状态管理优化

    • 如果项目较大且有较多共享状态,可以使用Vuex并适当优化store模块设计,确保仅关注必要的状态变化。
  8. 服务端渲染(SSR)

    • 对SEO友好的应用,可以考虑使用Vue服务器渲染来提供更快的首屏加载速度。
  9. 分析工具辅助优化

    • 使用Vue DevTools检查组件的状态和性能。
    • 结合Webpack Bundle Analyzer查看包体积,针对性地拆分大包。
    • 利用Lighthouse、PageSpeed Insights等工具评估网站性能并获取改进提示。
  10. 持续性能监控

    • 实施生产环境下的性能监控,例如通过Google Analytics跟踪页面加载速度、错误报告等指标。

以上列举了一些常见的Vue项目性能优化策略,实际优化过程中可能还需要结合项目的具体情况进行调整和实施。

21.vue中的spa应用如何优化首屏加载速度?

Vue.js单页面应用(SPA)的首屏加载速度优化可以采取以下多种策略:

  1. 代码分割与懒加载

    • 使用动态导入和路由懒加载。在大型项目中,通过import()vue-router中的异步路由配置实现组件级别的按需加载,仅加载用户当前访问所需的模块。
  2. 预渲染或服务器端渲染

    • 预渲染(Prerendering):针对SEO要求较高的页面,可以生成静态HTML文件,提升首屏内容的加载速度。
    • 服务器端渲染(SSR):对于初始加载性能有较高需求的场景,Vue提供了服务器端渲染方案,能够更快地向用户展示首屏内容。
  3. 资源优化

    • 对CSS和JavaScript进行压缩、合并,并利用Webpack等构建工具的Tree Shaking特性移除未使用的代码。
    • 图片优化:使用CDN加速图片加载,合理使用WebP格式,采用响应式图片处理,如srcset属性和sizes属性。
    • 资源缓存:设置HTTP缓存头,合理利用浏览器缓存机制减少网络请求。
  4. 减小主包体积

    • 按需引入第三方库,避免一次性引入整个库,例如使用babel-plugin-import或者webpack的externals功能。
    • 使用SplitChunksPlugin(Webpack 4+)或OptimizeModuleIdsPlugin(Webpack 5+)对公共模块进行拆分,减少重复加载。
    • 将非关键脚本放在body底部加载,确保首屏渲染所需的核心代码优先执行。
  5. 前端静态资源缓存

    • 利用Service Worker实现离线缓存和资源预加载,提高后续访问速度。
  6. 延迟加载非首屏内容

    • 对于首屏之外的内容,如滚动到视窗内才显示的部分,可以采用Intersection Observer API或者Vue的v-if结合scroll事件来实现懒加载。
  7. 优化数据获取

    • 对API请求进行分页处理,只加载首屏需要的数据,其余数据按需加载。
    • 延迟加载非必要的API请求,等待用户交互触发后再发起请求。
  8. 首屏骨架屏/Loading状态

    • 提供一个简化的骨架屏或Loading动画,让用户感知正在加载的同时掩盖白屏时间。
  9. 合理规划组件结构

    • 减少不必要的嵌套层级,优化组件树结构,降低渲染开销。
  10. 启用压缩传输

    • 开启GZIP压缩,减少网络传输的数据量。

通过综合运用上述策略,可以显著改善Vue SPA应用的首屏加载速度,提高用户体验。

22.Vue中的Key的作用是什么?

Vue.js中的key属性在渲染列表时起到非常重要的作用,其主要功能和目的如下:

  1. 优化虚拟DOM diff过程

    • 当Vue进行虚拟DOM的更新比较时(diff算法),如果元素有key属性,Vue会根据key来识别新旧节点的关系。这意味着具有相同key的元素会被认为是同一个逻辑节点,在组件状态改变导致重新渲染时,Vue能够更准确地判断哪些节点需要移动、哪些节点可以复用以及哪些节点需要被删除或新增。
  2. 保持组件状态

    • 在使用v-for指令遍历数组生成列表时,为每个循环项指定一个稳定的、唯一的key值至关重要。这样,即使列表项的顺序发生变化,Vue也能正确保留每个列表项的状态,避免了如表单输入内容丢失等问题。
  3. 提高渲染性能

    • 通过使用key,Vue能够在大规模列表更新时跳过不必要的元素重排操作,仅对位置改变或者新增/删除的元素执行最少的操作,从而显著提高渲染效率。
  4. 精准节点匹配

    • key充当了VNode标识符的角色,使得Vue能够快速定位到特定的子节点,这对于列表中大量节点的增删改查场景尤其有效。

综上所述,当我们在Vue中构建动态列表时,应确保为每一个v-for循环体内的元素设置一个合适的key值,这个值应当基于数据中稳定且唯一的身份标识,而不是仅仅依赖于索引(index)。若列表项目的顺序可能会频繁变动,使用索引作为key将可能导致不理想的性能表现和状态管理问题。

23.组件中写name选项有哪些好处

Vue.js组件中设置name选项有以下几个好处:

  1. 递归组件

    • 当一个组件需要递归调用自身时,必须为其定义name属性。在组件内部通过this.$options.components[自身的name]可以访问到该组件本身,从而实现递归渲染。
  2. 缓存管理(keep-alive)

    • 在使用<keep-alive>包裹动态组件时,Vue会根据组件的name来决定哪些组件实例应当被缓存。你可以通过includeexclude属性精确控制哪些组件应该被包含或排除在缓存策略内。
  3. 调试工具识别

    • Vue DevTools插件在调试Vue应用时,如果没有为组件设置name,可能会显示为匿名组件,这将不利于开发过程中的调试与追踪。当组件具有明确的name时,在DevTools中会更容易识别和定位各个组件及其状态。
  4. 代码可读性与维护性

    • 设置name属性提高了代码的可读性和可维护性,它提供了一种直观的方式来标识和引用组件,这对于大型项目或者团队协作尤为重要。
  5. 运行时日志与错误跟踪

    • 在某些情况下,Vue.js的运行时错误信息会包含组件的名字,这对于排查错误来源非常有用。
  6. 第三方库集成

    • 一些第三方库可能依赖于组件的name来进行特定功能的注册或查找,比如自定义指令、路由配置等。

总结来说,尽管name不是Vue组件的必填选项,但为了更好的开发体验、调试支持以及某些高级特性,推荐在编写组件时为它们指定有意义的名称。

24.说一下ref的作用是什么?

Vue.js 中的 ref 是一个特殊属性,用于给元素或组件注册引用信息。通过在模板中为 DOM 元素或子组件添加 ref 属性,Vue 提供了一种直接访问和操作这些元素或组件实例的方法。

ref的作用主要包括:

  1. 获取DOM元素引用

    • 当我们在HTML元素上设置ref属性(如 <input ref="myInput">),在Vue实例内部可以通过 this.$refs.myInput 访问到该DOM元素的实际引用,进而可以读取或修改其属性、调用方法等,例如获取或改变输入框的值。
  2. 访问子组件实例

    • 如果将 ref 应用在自定义组件上,那么 this.$refs 将引用到该子组件的实例,这样就可以调用子组件公开的方法,或者访问它的数据属性。
  3. 操作组件状态或执行方法

    • 通过 ref 注册的组件实例,可以在父组件中与子组件进行更深入的交互,比如控制子组件的行为、传递数据等。
  4. 与 Vue 生命周期配合使用

    • 由于 ref 引用是在组件渲染完成后才能生效,因此可以在组件的 mounted 或其他合适的生命周期钩子函数中使用 $refs 来执行需要依赖真实DOM的操作。
  5. 配合 keep-alive 组件保留状态

    • 当结合 keep-alive 组件动态切换时,通过 ref 可以保留组件的状态,即使组件被卸载后再次激活,仍能访问到之前的状态。

总结来说,Vue中的 ref 主要是为了方便开发者能够直接操作特定的DOM元素或组件实例,在复杂的应用场景下实现更灵活的交互和功能控制。

25.你的接口请求一般放在哪个生命周期中?为什么要这样做?

在 Vue.js 中,接口请求(即与服务器进行数据交互)通常会放在以下几个生命周期钩子函数中:

  1. created

    • 这个阶段发生在组件实例被创建之后,数据观测 (data) 和事件配置已完成,但模板还未渲染到 DOM 中。如果你的接口请求不需要依赖 DOM 渲染结果,并且你希望尽早获取数据以便在模板首次渲染时就能使用,则可以在 created 钩子中发起请求。
  2. beforeMount

    • 这个生命周期钩子在挂载开始之前被调用,此时模板已经编译好但是还没有挂载到 DOM 中。在这个阶段发起请求的情况相对较少,但如果需要在 DOM 挂载前就基于接口数据做一些计算或状态初始化,可以考虑在此处发起请求。
  3. mounted

    • 当组件完成挂载并且 DOM 已经更新后,mounted 钩子会被调用。如果你的接口请求依赖于已挂载的 DOM 或需要操作组件挂载后的实际DOM元素,那么在这里发起请求比较合适。

根据最佳实践,大多数情况下推荐在 createdmounted 生命周期钩子中发起接口请求。如果不需要等待 DOM 更新就可以发送请求,首选 created,因为它能更快地发出请求,有助于减少用户看到空白页面的时间。如果请求结果必须依赖于已挂载的 DOM 节点,则应该在 mounted 中发起请求。

此外,在某些特定场景下,例如使用 Vue Router 的路由组件中,为了确保当路由激活时才执行请求而不是在每次路由切换时都执行(即使目标路由是已经被访问过的),可以使用 beforeRouteEnterbeforeRouteUpdate 等路由守卫来精确控制接口请求的时机。

这篇关于Vue面试题,背就完事了的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/826161

相关文章

Vue3 的 shallowRef 和 shallowReactive:优化性能

大家对 Vue3 的 ref 和 reactive 都很熟悉,那么对 shallowRef 和 shallowReactive 是否了解呢? 在编程和数据结构中,“shallow”(浅层)通常指对数据结构的最外层进行操作,而不递归地处理其内部或嵌套的数据。这种处理方式关注的是数据结构的第一层属性或元素,而忽略更深层次的嵌套内容。 1. 浅层与深层的对比 1.1 浅层(Shallow) 定义

这15个Vue指令,让你的项目开发爽到爆

1. V-Hotkey 仓库地址: github.com/Dafrok/v-ho… Demo: 戳这里 https://dafrok.github.io/v-hotkey 安装: npm install --save v-hotkey 这个指令可以给组件绑定一个或多个快捷键。你想要通过按下 Escape 键后隐藏某个组件,按住 Control 和回车键再显示它吗?小菜一碟: <template

【 html+css 绚丽Loading 】000046 三才归元阵

前言:哈喽,大家好,今天给大家分享html+css 绚丽Loading!并提供具体代码帮助大家深入理解,彻底掌握!创作不易,如果能帮助到大家或者给大家一些灵感和启发,欢迎收藏+关注哦 💕 目录 📚一、效果📚二、信息💡1.简介:💡2.外观描述:💡3.使用方式:💡4.战斗方式:💡5.提升:💡6.传说: 📚三、源代码,上代码,可以直接复制使用🎥效果🗂️目录✍️

【前端学习】AntV G6-08 深入图形与图形分组、自定义节点、节点动画(下)

【课程链接】 AntV G6:深入图形与图形分组、自定义节点、节点动画(下)_哔哩哔哩_bilibili 本章十吾老师讲解了一个复杂的自定义节点中,应该怎样去计算和绘制图形,如何给一个图形制作不间断的动画,以及在鼠标事件之后产生动画。(有点难,需要好好理解) <!DOCTYPE html><html><head><meta charset="UTF-8"><title>06

计算机毕业设计 大学志愿填报系统 Java+SpringBoot+Vue 前后端分离 文档报告 代码讲解 安装调试

🍊作者:计算机编程-吉哥 🍊简介:专业从事JavaWeb程序开发,微信小程序开发,定制化项目、 源码、代码讲解、文档撰写、ppt制作。做自己喜欢的事,生活就是快乐的。 🍊心愿:点赞 👍 收藏 ⭐评论 📝 🍅 文末获取源码联系 👇🏻 精彩专栏推荐订阅 👇🏻 不然下次找不到哟~Java毕业设计项目~热门选题推荐《1000套》 目录 1.技术选型 2.开发工具 3.功能

Vue3项目开发——新闻发布管理系统(六)

文章目录 八、首页设计开发1、页面设计2、登录访问拦截实现3、用户基本信息显示①封装用户基本信息获取接口②用户基本信息存储③用户基本信息调用④用户基本信息动态渲染 4、退出功能实现①注册点击事件②添加退出功能③数据清理 5、代码下载 八、首页设计开发 登录成功后,系统就进入了首页。接下来,也就进行首页的开发了。 1、页面设计 系统页面主要分为三部分,左侧为系统的菜单栏,右侧

荣耀嵌入式面试题及参考答案

在项目中是否有使用过实时操作系统? 在我参与的项目中,有使用过实时操作系统。实时操作系统(RTOS)在对时间要求严格的应用场景中具有重要作用。我曾参与的一个工业自动化控制项目就采用了实时操作系统。在这个项目中,需要对多个传感器的数据进行实时采集和处理,并根据采集到的数据及时控制执行机构的动作。实时操作系统能够提供确定性的响应时间,确保关键任务在规定的时间内完成。 使用实时操作系统的

【VUE】跨域问题的概念,以及解决方法。

目录 1.跨域概念 2.解决方法 2.1 配置网络请求代理 2.2 使用@CrossOrigin 注解 2.3 通过配置文件实现跨域 2.4 添加 CorsWebFilter 来解决跨域问题 1.跨域概念 跨域问题是由于浏览器实施了同源策略,该策略要求请求的域名、协议和端口必须与提供资源的服务相同。如果不相同,则需要服务器显式地允许这种跨域请求。一般在springbo

HTML提交表单给python

python 代码 from flask import Flask, request, render_template, redirect, url_forapp = Flask(__name__)@app.route('/')def form():# 渲染表单页面return render_template('./index.html')@app.route('/submit_form',

一些其他面试题

阿里二面:那你来说说定时任务?单机、分布式、调度框架下的定时任务实现是怎么完成的?懵了。。_哔哩哔哩_bilibili 1.定时算法 累加,第二层每一个格子是第一层的总时间400 ms= 20 * 20ms 2.MQ消息丢失 阿里二面:高并发场景下引进消息队列有什么问题?如何保证消息只被消费一次?真是捏了一把汗。。_哔哩哔哩_bilibili 发送消息失败