跟chatGPT一起复习前端 —— Vue

189 阅读8分钟

前言

又到一波面试准备的时刻,整理了一波前端相关要点内容,配合chatGPT完成要点内容整理,有纠正错误和需要补充的小伙伴可以在这里留言,及时更新。

双向绑定原理

Vue.js的双向数据绑定是通过数据劫持结合发布-订阅者的模式实现的。Vue2和Vue3的双向数据绑定原理有所不同。

在Vue2中,双向数据绑定是通过数据劫持结合发布-订阅者的模式实现的。它通过Object.defineProperty()来劫持对象属性的getter和setter操作,在数据变动的时候发布消息给订阅者,触发响应的监听回调。对于Object.defineProperty,有三个参数,

  • 第一个参数:要定义属性的对象的名字,
  • 第二个参数:要定义或修改的属性的名称或Symbol,
  • 第三个参数:将被定义或修改的属性描述符。

在Vue3中,双向数据绑定是通过Proxy对象实现的。Proxy可以监听对象和数组等复杂类型的变化,并且可以监听到数组下标和length属性的变化。相比于Object.defineProperty(),Proxy更加强大和灵活。

defineProperty和proxy的区别

  • Object.defineProperty 和 Proxy 都是 JavaScript 中的元编程 API,它们都可以用来拦截对象的操作。它们之间的区别主要有以下几点:
  • Object.defineProperty 是 ES5 的方法,而 Proxy 是 ES6 的方法;
  • Object.defineProperty 只能对单个属性进行控制,而 Proxy 可以对整个对象进行控制;
  • Object.defineProperty 不能监听到数组下标变化和对象新增属性,而 Proxy 可以;
  • Object.defineProperty 是劫持对象属性,而 Proxy 是代理整个对象;
  • Object.defineProperty 的缺陷是无法检测到对象属性的新增或删除,只能追踪对象已有数据是否被修改,无法追踪新增属性和删除属性;而 Proxy 可以拦截更多的操作,比如 has、deleteProperty、ownKeys 等。

Vue2生命周期及各个周期的特性

Vue实例有一个完整的生命周期,也就是说从开始创建、初始化数据、编译模板、挂载DOM、渲染-更新-渲染、卸载等一系列过程,我们称为Vue实例的生命周期,钩子就是在某个阶段给你一个做某些处理的机会。

Vue生命周期分为8个阶段:创建前/后,载入前/后,更新前/后,销毁前/后2。每个阶段都有相应的钩子函数可以调用。下面是各个周期的特性:

  • beforeCreate:在数据观测和初始化事件还未开始。
  • created:此时状态: Vue 里的数据在内存中已经创建完毕,但是还未开始编译模板。
  • beforeMount:在挂载之前被调用:相关的 render 函数首次被调用。
  • mounted:el 被新创建的 vm.$el 替换,并挂载到实例上去之后调用该钩子。
  • beforeUpdate:数据更新时调用,发生在虚拟 DOM 重新渲染和打补丁之前。
  • updated:由于数据更改导致的虚拟 DOM 重新渲染和打补丁,在这之后会调用该钩子。
  • beforeDestroy:实例销毁之前调用。在这一步,实例仍然完全可用。
  • destroyed:实例销毁后调用。

单变量对应多视图Vue怎样去更新状态

Vue.js中,当一个变量对应多个视图时,可以使用computed属性来实现。computed属性是一个计算属性,它的值是由其他变量计算得出的,当其他变量发生变化时,computed属性会自动更新。你可以在computed属性中使用getter和setter方法来实现对变量的读写操作。如果你想强制更新视图,可以使用$forceUpdate()方法。

Vuex的理解与使用

Vuex是专门为Vue服务,用于管理页面的数据状态、提供统一数据操作的生态系统,相当于数据库mongoDB,MySQL等,任何组件都可以存取仓库中的数据。Vuex是一个专为Vue.js应用程序开发的状态管理模式 + 库。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。

更多可参考 vue中使用vuex(超详细)

MVVM 模式的优缺点,与 MVC 的区别

MVVM 模式是一种软件架构模式,它将应用程序分为三个部分:模型(Model)、视图(View)和视图模型(ViewModel)。其中,模型表示应用程序的数据和业务逻辑,视图负责显示用户界面,而视图模型则充当了模型和视图之间的桥梁,它负责将模型中的数据转换为视图可以使用的数据,并将视图中的用户操作转换为模型可以使用的操作。相比于 MVC 模式,MVVM 模式具有以下优点:

  • 解耦:MVVM 模式将应用程序分为三个部分,每个部分都有自己的职责,这样可以使得应用程序更加容易维护和扩展。
  • 可测试性:MVVM 模式中,视图模型是独立于视图和模型的,因此可以很方便地对其进行单元测试。
  • 数据双向绑定:MVVM 模式中,视图和视图模型之间采用数据双向绑定的方式进行通信,这样可以使得应用程序更加灵活和响应式。

MVC 模式与 MVVM 模式的区别主要在于:

  • 职责不同:MVC 模式将应用程序分为三个部分:模型、视图和控制器(Controller),其中控制器负责协调模型和视图之间的通信。而 MVVM 模式则将控制器替换成了视图模型(ViewModel),它负责协调模型和视图之间的通信。
  • 数据绑定方式不同:MVC 模式中,控制器负责将模型中的数据传递给视图。而 MVVM 模式中,则采用了数据双向绑定的方式进行通信。

Vue的组件通信

Vue组件通信的方式有很多种,包括但不限于:props、emitemit、parent/$children、provide/inject、event bus、vuex等。

  • props是父组件向子组件传递数据的方式;
  • $emit是子组件向父组件传递数据的方式;
  • parent/parent/children是访问父/子组件实例的方式;
  • provide/inject是祖先组件向后代组件传递数据的方式;
  • event bus是通过事件中心来传递数据的方式;
  • vuex是一种全局状态管理工具,可以在任何组件中访问和修改状态。

Vue中是如何检测数组的变化

由于 JavaScript 的限制,Vue 不能检测以下变动的数组:

当你利用索引直接设置一个项时,例如: vm.items [indexOfItem] = newValue 当你修改数组的长度时,例如: vm.items.length = newLength 但是Vue对数组的7个变异方法(push、pop、shift、unshift、splice、sort、reverse)实现了响应式。如果你想要检测数组的变化,可以使用Vue提供的$set方法。

Vue组件中的data为什么要写成函数形式

在Vue组件中,data属性必须是一个函数,而不能直接把一个对象赋值给它。这是因为在Vue组件中,每个实例都需要维护一份被返回对象的独立拷贝,如果直接将一个对象赋值给data属性,那么所有的实例将共享同一个对象,这样会导致状态污染的问题。而将data属性设置为函数,则可以保证每个实例都有自己的数据对象,从而避免了状态污染的问题。

换句话说,data属性是一个函数,每次创建组件实例时都会调用该函数返回一个新的数据对象。这样就可以保证每个组件实例都有自己独立的数据对象了。

nextTick 是做什么用的,其原理是什么

nextTick 是 Vue 提供的一个全局的 API,由于 Vue 的异步更新策略导致我们对数据的修改不会立马体现到 DOM 上,此时如果想要立即获取更新后的 DOM 的状态,就需要使用这个方法。Vue 在更新 DOM 时是异步执行的。nextTick 方法的作用就是让代码延迟执行,等到 DOM 更新后再执行。

其原理是通过异步队列来实现的。当数据发生变化时,Vue 会开启一个异步队列,将需要执行的回调函数放入队列中,等到下一次事件循环时才会执行这些回调函数。这样做可以避免频繁操作 DOM 导致性能问题。

Vue的模板编译原理

Vue的模板编译原理主要分为三个部分:

  1. 将模板字符串转换成element AST(解析器parser),使用大量的正则表达式对template字符串进行解析,将标签、指令、属性等转化为抽象语法树AST。。
  2. 对AST进行静态节点标记,主要用来做虚拟DOM的渲染优化(优化器optimizer),遍历AST,找到其中的一些静态节点并进行标记,方便在页面重渲染的时候进行diff比较时,直接跳过这一些静态节点,优化runtime的性能。。
  3. 使用element AST生成render函数代码字符串(代码生成器code generator)。

这个过程中,Vue会将模板字符串转换成一个抽象语法树(AST),然后遍历这个树,生成一个渲染函数。这个渲染函数可以被用来生成虚拟DOM。

computed 与 watch 的差异

computed 和 watch 都是 Vue 中的响应式 API,但是它们的功能不同。computed 是计算属性,watch 是监听一个值的变化,然后执行对应的回调。computed 中的函数所依赖的属性没有发生变化,那么调用当前的函数的时候会从缓存中读取,而 watch 在每次监听的值发生变化的时候都会执行回调。

vue-router的模式和对应原理

vue-router 是 Vue.js 的官方路由管理器。它与 Vue.js 核心深度集成,使得构建单页面应用变得易如反掌。Vue Router 提供的模式有三种:hash 模式、history 模式和 abstract 模式。

其中 hash 模式是通过监听 URL 中的 hash 值变化来实现的,而 history 模式是利用了 HTML5 History API 中新增的 pushState() 和 replaceState() 方法来完成 URL 跳转而无须重新加载页面。

Vue Router 的核心是路由系统。路由系统包括路由表、匹配器和导航守卫。路由表是一个映射表,将 URL 映射到组件中。匹配器则负责匹配 URL 和路由表中的路径,以确定要渲染哪个组件。导航守卫则负责在路由切换时执行一些操作,例如验证用户是否登录等。

vue-router 中的导航钩子

vue-router 中的导航钩子有三种,分别是:1.全局导航钩子;2.组件内的钩子;3.单独路由独享组,主要是用来拦截导航,让他完成跳转或取消。

  • 全局导航钩子有:beforeEach、beforeResolve、afterEach。
  • 组件内的钩子有:beforeRouteEnter、beforeRouteUpdate、beforeRouteLeave。
  • 单独路由独享组有:beforeEnter。

这些导航钩子可以用来做很多事情,比如:全局拦截路由、在路由跳转前做一些操作、在路由跳转后做一些操作等等。

Vue中 key 值的作用

在Vue.js中,key是一个特殊的属性,主要作用于Vue的virtual DOM算法,在diff new nodes list和old nodes list时,作为识别VNode的一个线索。Vue会尽可能高效地渲染元素,通常会复用已有元素而不是从头开始渲染,因此使用key值可以提高渲染效率,同理,改变某一元素的key值会使该元素重新被渲染。

Vue中常见的修饰符

Vue中常见的修饰符有如下几种:

表单修饰符:lazy、number、trim 事件修饰符:stop、prevent、capture、self、once、passive 鼠标按钮修饰符:left、right、middle 键盘修饰符:enter、tab、delete、space、esc、up、down、left、right、ctrl、alt、shift、meta v-bind修饰符:prop、camel、sync 这些修饰符可以让指令以某种方式绑定,从而改变其行为。例如,v-on 指令可以添加事件监听器,但是通过添加修饰符,可以改变其行为。例如,使用 .prevent 修饰符可以告诉 v-on 指令对于触发的事件调用 event.preventDefault()。

Vue中常用的指令

  • v-if:用于根据条件显示或隐藏元素。
  • v-for:用于循环一个数组或对象,并将其中每个值映射到相应的元素。
  • v-bind:用于绑定一个或多个属性,或者一个组件 prop 到表达式。当表达式的值改变时,绑定的目标就会自动更新。
  • v-on:用于监听 DOM 事件,并在触发时执行一些 JavaScript 代码。
  • v-model:用于在表单控件或组件上创建双向数据绑定。
  • v-show:与v-if类似,但是不会对DOM进行频繁的添加和删除操作,而是通过修改CSS来控制元素的显示和隐藏。
  • v-text:更新元素的文本内容。
  • v-html:更新元素的innerHTML。注意:容易被XSS攻击,请谨慎使用。
  • v-cloak:这个指令保持在元素上直到关联实例结束编译。和 CSS 规则如 [v-cloak] { display: none } 一起用时,这个指令可以隐藏未编译的 Mustache 标签直到实例准备完毕。
  • v-pre:跳过这个元素和它的子元素的编译过程。可以用来显示原始 Mustache 标签。

v-show 与 v-if 的区别

v-show和v-if都是Vue框架中的指令,它们的作用都是控制元素的显示和隐藏。区别在于:

v-if是创建和删除元素,而v-show只是改变元素中的display样式属性。 v-if的切换消耗高,v-show的初始渲染消耗高。 v-show的性能比v-if高。 如果需要频繁地让元素在显示和隐藏之间切换,建议使用v-show;如果不需要频繁切换,建议使用v-if。

keep-alive 组件的作用与实现原理

keep-alive是Vue内置的一个组件,能够缓存不活动的组件,防止重复渲染DOM。一般情况下,组件进行切换的时候,默认会进行销毁,如果有需求,某个组件切换后不进行销毁,而是保存之前的状态,那么就可以利用keep-alive来实现。

在Vue.js中,keep-alive的实现原理是通过LRU缓存策略来实现的。当keep-alive包裹动态组件时,会缓存不活动的组件实例,而不是销毁它们。include和exclude属性可以用于控制哪些组件被缓存或不被缓存。max属性可以用于控制最多缓存多少个组件实例。

Vue的虚拟dom

Vue的虚拟DOM是将多次DOM操作保存在一个JS对象(虚拟DOM对象)中,然后用这个JS对象一次性的去更新DOM操作,这样就避免了很多无效的计算。Vue通过编译将模板转换成渲染函数,执行渲染函数就可以得到一个虚拟节点树,使用虚拟节点数就可以渲染页面。虚拟DOM在Vue中主要提供与真实节点对应的虚拟节点vnode,然后需要将vnode和oldVnode进行比对,然后更新视图,对比两个虚拟节点的算法是patch算法。

Vue.js中的patch算法是通过对新旧两个VNode节点进行比较,然后通过对比结果找出差异的属性或节点进行按需更新。在对比的过程中,Vue采用深度优先,同级比较的方式进行比较,同级比较就是说它不会跨越结构进行比较,在判断两个节点是否相同的时候,是根据虚拟节点的key和tag来进行判断的。

Vue 中插槽类型

Vue 中的插槽主要分为三种类型:默认插槽、具名插槽和作用域插槽。默认插槽是指没有被命名的插槽,具名插槽是指被命名的插槽,作用域插槽是指可以将子组件中的数据传递到父组件中的插槽。

默认插槽可以在子组件中使用,而具名插槽可以在父组件中使用。作用域插槽可以让父组件访问子组件中的数据,从而实现更加灵活的组件设计。

mixin的理解

Mixin是一种编程模式,在面向对象编程中,Mixin是一个类,它包含了其他类可以使用的方法的实现。Mixin的作用是为了添加某些(可选的)功能,通常混入Mixin的类和Mixin类本身不是is-a的关系。在Vue中,Mixin允许你封装一块在应用的其他组件中都可以使用的函数1。如果您需要在多个组件之间共享功能,则可以使用mixin。mixin是一个对象,其中包含要添加到组件中的选项。

Mixin的优点是可以减少代码重复,提高代码的可重用性和可维护性。Mixin的缺点是可能会导致代码的复杂性增加,因为它们可以引入许多不同的方法和属性。此外,Mixin可能会导致命名冲突和方法覆盖问题。

Vue3新特性

  • 响应式API
  • Composition API
  • Teleport
  • Suspense
  • Fragment
  • 全局API的修改
  • 自定义指令的变化
  • v-model的变化
  • 新的组件API
  • 新的生命周期函数
  • 支持tree-shaking;
  • 暴露了自定义渲染API;
  • 新增三个组件(Fragment、Teleport、Suspense)等。

Vue3响应式API是什么?

Vue3响应式API是Vue3中最核心的特性之一。它是基于Proxy实现的,用于代理对象类型。Vue3中能够将对象变成响应式的API有两个:reactive和shallowReactive。其中,reactive能够将对象变成响应式的API,不管对象有多少层;而shallowReactive只代理最外层对象。

除此之外,还有ref和shallowRef,它们是用来代理基本类型的。ref对象是可更改的,也就是说你可以为.value赋予新的值。它也是响应式的,即所有对.value的操作都将被追踪,并且写操作会触发与之相关的副作用。如果将一个对象赋值给ref,那么这个对象将通过reactive()转为具有深层次响应式的对象。这也意味着如果你想要让一个嵌套对象变成响应式的,你需要使用reactive()而不是ref()。

Vue3的VueUse是什么

VueUse是一套Vue Composition API的常用工具集,是目前世界上Star最高的同类型库之一。它的初衷就是将一切原本并不支持响应式的JS API变得支持响应式,省去程序员自己写相关代码。

VueUse提供了许多实用程序函数,这些函数可以帮助您更轻松地使用Vue Composition API。以下是一些常用的实用程序函数:

  • useMouse:获取鼠标位置
  • useLocalStorage:处理本地存储
  • useIntersectionObserver:检测元素可见性
  • useDebounce:防抖动
  • useThrottle:节流
  • useClickAway:在点击元素外部时触发回调
  • useEvent:添加事件监听器
  • useTitle:动态更改文档标题
  • useFavicon:动态更改文档图标

Vue3 的 Teleport 是什么

Teleport 是 Vue3 中的一个新特性,它是一种能够将我们的模板移动到 DOM 中 Vue app 之外的其他位置的技术。如果我们嵌套在 Vue 的某个组件内部,那么处理嵌套组件的定位、z-index 和样式就会变得很困难。使用 Teleport 就可以方便地解决组件间 css 层级问题。

Vue2和Vue3的区别

  1. 性能方面:Vue3 的性能比 Vue2 快 1.2~2 倍;
  2. 响应式原理:Vue2 的响应式数据写在 data 中,而 Vue3 使用 reactivity API 创建;
  3. 组件方面:Vue3 新增了三个组件(Fragment、Teleport、Suspense)等;
  4. 模板方面:Vue3 支持 Fragment,就是说在组件可以拥有多个根节点;
  5. API 方面:Vue3 引入了 Composition API,暴露了自定义渲染 API;
  6. 构建工具方面:Vue3 支持 tree-shaking 等。

Vue3 Diff算法和 Vue2 的区别

Vue3 的 diff 算法相比 Vue2 有以下几个不同点:

  • Vue2 的核心 Diff 算法采用了双端比较的算法,同时从新旧 children 的两端开始进行比较,借助 key 值找到可复用的节点,再进行相关操作。相比 React 的 Diff 算法,同样情况下可以减少移动节点次数,减少不必要的性能损耗,更加的优雅。
  • Vue3 的核心 Diff 算法采用的是去头尾的最长递增子序列算法。这是一道经典的算法问题,它依次遍历新旧 children 中的节点,找到最长递增子序列,然后根据这个子序列进行 DOM 操作。这种算法可以大大减少 DOM 操作次数,提高渲染性能。
  • Vue3 的 Diff 算法还引入了 Block Tree 和 Patch Flag 等概念,可以更加精细地控制组件的更新和渲染。

composition API 与 options API的区别

Vue.js 的 Composition API 是 Vue.js 3 中的新特性,它是一种新的组件组织方式,可以将逻辑相关的代码放在一起,而不是像 Options API 那样将它们分散在不同的选项中。Composition API 可以让我们更好地组织代码,使其更易于阅读和维护。

Composition API与React Hook的区别

Composition API 和 React Hook 都是用于解决函数式组件中状态管理的问题。它们的主要区别在于,Composition API 是 Vue.js 3 中的新特性,而 React Hook 是 React 中的特性。Composition API 是基于 Vue 的响应式系统实现的,而 React Hook 则是基于 React 的状态钩子实现的。

Composition API 和 React Hook 都可以让我们在函数式组件中使用状态,但是它们的实现方式不同。Composition API 是基于 Vue 的响应式系统实现的,而 React Hook 则是基于 React 的状态钩子实现的。Composition API 可以让我们更好地组织代码,使其更易于阅读和维护。React Hook 则可以让我们在函数式组件中使用状态,而不需要使用类组件。

setup 函数

setup 函数是 Vue.js 3 中的一个新特性,它是组合式 API 的一部分。setup 函数是一个函数,具有 return,return 函数中定义的变量,把其暴露给模板。setup 函数的第一个参数是组件的 props。和标准的组件一致,一个 setup 函数的 props 是响应式的,并且会在传入新的 props 时同步更新。

reactive、 shallowReactive 函数

reactive 函数用于创建深层响应式对象,接收一个普通对象,返回一个响应式的数据对象。响应式转换是“深层”的——它影响所有嵌套属性。shallowReactive 函数用于创建浅层响应式对象,接收一个普通对象,返回一个响应式的数据对象。响应式转换是“浅层”的——只影响对象本身。

ref、 shallowRef 、isRef、toRefs 函数

ref 函数接受一个内部值并返回一个响应式且可变的 ref 对象。ref 对象仅有一个 .value property,指向该内部值。如果将对象分配为 ref 值,则它将被 reactive 函数处理为深层的响应式对象。

shallowRef 函数用于创建浅层响应式对象,接收一个普通对象,返回一个响应式的数据对象。响应式转换是“浅层”的——只影响对象本身。

isRef 函数用于检查一个值是否为 ref 对象,返回值为布尔类型。

toRefs 函数将响应式对象转换为普通对象,其中结果对象的每个 property 都是指向原始对象相应 property 的 ref。主要功能:当从组合式函数 (.js) 返回响应式对象时,用toRefs就可以在不丢失响应性的情况下对返回的对象进行解构/展开.

readonly、isReadonly、shallowReadonly函数

readonly 函数接受一个对象 (不论是响应式还是普通的) 或是一个 ref,返回一个原值的只读代理。只读代理是深层的:对任何嵌套属性的访问都将是只读的。它的 ref 解包行为与reactive()相同,但解包得到的值是只读的。

shallowReadonly 函数也用于创建一个只读数据,但是这个只读只是第一层只读,非深度只读。

isReadonly 函数用于检查一个值是否为只读代理,返回值为布尔类型。

watch 和 watchEffect 的区别

watch 和 watchEffect 都是 Vue3 中的监听器,用于监听响应式数据的变化。不同的是它们监听数据变化的方式不同。

watch 需要明确指定需要监听的响应式数据,只有在指定的响应式数据发生变化时才会执行回调函数。而 watchEffect 则是隐式的监听回调函数中响应数据,只要传入的函数带有依赖就会自动追踪。

另外,watchEffect 初始化时,一定会执行一次(收集要监听的数据,不然不知道监听的是什么),而 watch 只有你设置了初始化监听才会监听。

Vue3 的生命周期

  • beforeCreate:在实例初始化之后,数据观测 (data observer) 和 event/watcher 事件配置之前被调用。
  • created:在实例创建完成后被立即调用。在这一步,实例已完成以下的配置:数据观测 (data observer),属性和方法的运算,watch/event 事件回调。然而,挂载阶段还没开始,$el 属性目前不可见。
  • beforeMount:在挂载开始之前被调用:相关的 render 函数首次被调用。
  • mounted:el 被新创建的 vm.$el 替换,并挂载到实例上去之后调用该钩子函数。此时实例的根 DOM 元素被新创建的 vm.$el 替换,$el 属性指向了新创建的 DOM 元素上。
  • beforeUpdate:数据更新时调用,发生在虚拟 DOM 重新渲染和打补丁之前。这里适合在更新之前访问现有的 DOM,比如手动移除已添加的事件监听器。
  • updated:由于数据更改导致的虚拟 DOM 重新渲染和打补丁,在这之后会调用该钩子函数。当这个钩子函数被调用时,组件 DOM 已经更新,所以你现在可以执行依赖于组件 DOM 的操作。
  • beforeUnmount:在卸载开始之前被调用。此时实例仍然完全可用。
  • unmounted:在卸载完成后被调用。这个钩子函数被调用后,对应 Vue 实例的所有指令都被解绑定,所有事件监听器都被移除,所有子实例也都被销毁。
  • errorCaptured:当捕获一个来自子孙组件的错误时被调用。此钩子会收到三个参数:错误对象、发生错误的组件实例以及一个包含错误来源信息的字符串。此钩子可以返回 false 以阻止该错误继续向上传播。
  • renderTracked:当渲染函数跟踪一个依赖项时被调用。此钩子接收跟踪对象作为其唯一参数。
  • renderTriggered:当渲染函数触发更新时被调用。此钩子接收触发更新的组件作为其唯一参数。

pinia的理解和使用

Pinia 是一个用于 Vue 的状态管理库,类似 Vuex,是 Vue 的另一种状态管理方案。Pinia 支持 Vue2 和 Vue3。Pinia 的优势在于它是类型安全的、可扩展的和模块化的,可以让你忘记你正在使用一个存储库。Pinia 还提供了一些有用的功能,如插件、插件 API 和插件生命周期钩子等。

pinia和Vuex的区别

与 Vuex 相比,Pinia 提供了一个更简单的 API,具有更少的规范,提供了 Composition-API 风格的 API,最重要的是,在与 TypeScript 一起使用时具有可靠的类型推断支持。

Pinia API 与 Vuex ≤4 有很大不同,即:

  • mutations 不再存在。他们经常被认为是 非常 冗长。他们最初带来了 devtools 集成,但这不再是问题。
  • 无需创建自定义复杂包装器来支持 TypeScript,所有内容都是类型化的,并且 API 的设计方式尽可能利用 TS 类型推断。
  • 不再需要注入、导入函数、调用函数、享受自动完成功能!
  • 无需动态添加 Store,默认情况下它们都是动态的,您甚至都不会注意到。请注意,您仍然可以随时手动使用 Store 进行注册,但因为它是自动的,您无需担心。
  • 不再有 modules 的嵌套结构。您仍然可以通过在另一个 Store 中导入和 使用 来隐式嵌套 Store,但 Pinia 通过设计提供平面结构,同时仍然支持 Store 之间的交叉组合方式。 您甚至可以拥有 Store 的循环依赖关系。
  • 没有 命名空间模块。鉴于 Store 的扁平架构,“命名空间” Store 是其定义方式所固有的,您可以说所有 Store 都是命名空间的。