Vue 的笔记

138 阅读28分钟

Vue 的知识点

1、vue2 的生命周期

vue完整的生命周期包括了创建、更新、销毁三个阶段

  • 创建阶段

    • beforeCreate(创建前): 数据观测初始化事件未开始,不能访问data、computed、watch、methods上的数据方法。
    • create(创建后):实例创建完成立即被调用。在这个阶段,实例已经完成数据观测属性方法的运算,可以访问data、computed、watch、methods上的数据方法,但此时渲染节点未挂载到DOM上。
  • 挂载阶段

    • beforeMount(挂载前):Vue实例还未挂到页面HTML上,相关的 render 函数首次被调用,此时可以做网络请求等操做。
    • mouted(挂载后):Vue实例挂载完毕,可以进行DOM操做
  • 更新阶段

    • beforeUpdate(更新前):数据更新时调用,还未渲染到页面,发生在虚拟DOM重新渲染和打补丁之前
    • updated(更新后):数据更新后调用,发生在虚拟DOM重新渲染和打补丁之后
  • 销毁阶段

    • beforDestriy(销毁前):在实例销毁之前调用。在这个阶段,实例仍然完全可用
    • destroyed(销毁后):在实例销毁之后调用。在这个阶段,所有的事件监听器子组件已被销毁
  • 错误捕获

    • errorCaptured:用来捕获子组件生命周期钩子函数中的错误。可以在组件自身内部处理错误或者向上级组件传递错误信息。
  • 遇到 keep-alive 会出现以下俩个生命周期 activated、deactivated

    • 当组件首次挂载时,会触发 mounted 钩子。
    • 当组件被切换并激活时,会触发 activated 钩子。
    • 当组件被切换并停用时,会触发 deactivated 钩子。
    • 当组件完全销毁时,会触发 destroyed 钩子。

Vue3 的生命周期

  • 创建阶段

    • setup 取代 beforeCreate、create
  • 挂载阶段

    • onBeforeMount 取代 beforeMount,在挂载开始之前调用
    • onMounted 取代 mouted, 在挂载完成之后调用
  • 更新阶段

    • onBeforeUpdate 取代 beforeUpdate, 在数据更新之前调用
    • onUpdated 取代 updated, 在数据更新之后调用
  • 销毁阶段

    • onBeforeUnmount 取代 beforDestriy, 在组件卸载之前调用
    • onUnmounted 取代 destroyed, 在组件卸载之后调用
  • 遇到 keep-alive 会出现以下俩个生命周期 onActivated、onDeactivated

    • 组件首次加载时:
      • setup
      • onBeforeMount
      • onMounted
    • 组件被 keep-alive 缓存并激活时:
      • onActivated
    • 组件被 keep-alive 缓存并停用时:
      • onDeactivated
    • 组件从 DOM 中完全移除时(如果不再需要):
      • onBeforeUnmount
      • onUnmounted

为何 vue2 对数组下标操作,不能触发响应式呢?

  • Vue 2 的响应式系统依赖于 Object.defineProperty,而数组的长度可能会比较长,如果对每个数组元素都加上 getter、setter 的话,性能开销会非常高,尤其是大数组的情况下。

  • 为了确保对数组的修改能够触发响应式更新,Vue2 提供了两种主要的解决方案:

    • 使用 Vue.set 方法来添加新的数组元素或修改现有元素。这样可以确保新的元素被响应式地添加并触发视图更新。
    Vue.set(this.items, 1, newValue); // 将索引为 1 的元素更新为 newValue
    
    • 使用 push、pop、shift、unshift、splice 等变异方法来修改数组。这些方法已经被 Vue 包装成响应式的,可以触发视图更新。
    this.items.splice(index, 1, newValue); // 替换数组中的一个元素
    

vue3 和 vue2 的区别

  • Composition API: Vue 3 引入了 Composition API,这是一种新的组织组件逻辑的方式,可以让代码更加结构化和可维护,特别是在处理复杂逻辑时更加方便。

  • 性能优化: Vue 3 在底层进行了许多性能优化,包括更高效的虚拟 DOM 渲染、更新算法优化以及更好的 Tree-Shaking 支持,使得应用程序在性能上有了显著的提升。

  • Typescript 支持: Vue 3 更加深度集成了 Typescript,提供了更好的类型推断和类型支持,使得代码更加健壮和可靠。

  • 更小的 bundle 大小: Vue 3 的核心代码库经过优化,生成的 bundle 大小更小,这对于移动端或者需要快速加载的应用程序来说尤为重要。

  • 全局 API 的变化: Vue 3 中一些全局 API 发生了变化,例如全局 API 的导入方式和部分配置选项的变更,需要开发者在迁移时注意适配。

  • Vue 3 不再推荐直接修改原型链来挂载全局属性: 在 Vue 2 中,可以直接将全局对象的实例挂载到 Vue 的原型链上。而在 Vue 3 中,不再推荐这样做,而是通过 config.globalProperties 来承载全局属性。

  • Vue 2 和 Vue 3 的 Diff 算法优化: Vue 3 对比 Vue 2 的 diff 算法进行了优化。Vue 2 使用的是简单的双端比较算法,而 Vue 3 通过增加静态标记和块(block)机制,提高了对静态节点的检测和处理效率,减少了不必要的 DOM 更新,从而提升了渲染性能。这样的优化使 Vue 3 在处理大型应用和频繁更新时表现更加优越。

2、vue的样式作用域

  • Vue.js 提供了 <style scoped> 标签,可以将样式限定在当前组件的作用域内,这样样式只会影响当前组件的元素,不会影响到其他组件。
    <style scoped>
    /* 这里的样式只会作用于当前组件 */
    </style>
    
    
  • 如果需要修改 element等UI组件的样式时,可以使用 ::v-deep
    <style scoped>
    /* 在 scoped 样式中使用 ::v-deep 来穿透 Element UI 的样式封装 */
    .el-input ::v-deep {
    /* 修改输入框的样式 */
    }
    </style> 
    
  • scoped 属性的实现原理主要是利用 CSS 的作用域限定规则Vue 编译器的处理。当 Vue 编译器遇到带有 scoped 属性<style> 标签时,它会在编译过程中对样式进行转换,生成一个唯一属性选择器,然后将该选择器添加到组件中的每个样式规则选择器前面。如下面例子的,[data-v-f3f3eg9] 是一个带有唯一标识符属性选择器,它会自动添加到组件的每个样式规则的选择器前面。这样一来,样式就变得具有了局部作用域,只会影响到当前组件的 DOM 元素,而不会影响到其他组件的样式。
    <style scoped>
    .example {
    color: red;
    }
    </style>
      ↑
    转换为
      ↓
    <style>
    .example[data-v-f3f3eg9] {
    color: red;
    }
    </style>
    
    

3、vue 指令有哪些?

  • v-if: 根据表达式的值条件性地渲染元素。
  • v-show: 根据表达式的值条件性地显示或隐藏元素。
  • v-for: 基于数组或对象的值循环渲染元素。
  • v-on: 绑定事件监听器,用于监听 DOM 事件,并触发 Vue 实例中的方法。
  • v-bind: 动态地绑定 HTML 属性,可以简写为 :。
  • v-model: 在表单元素上创建双向数据绑定,用于实现表单输入应用状态之间的双向绑定。
  • v-html: 将数据作为 HTML 解析,并将结果渲染元素内部
  • v-text: 将数据作为纯文本渲染到元素内部,会覆盖原有的内容。

4、vue的插槽是什么?

  • Vue 的插槽(Slot)是一种机制,用于在父组件中子组件内容插入到指定的位置。插槽允许父组件子组件中定义占位符,并在实例化子组件时填充内容,从而实现组件间更灵活交互和组合

  • Vue 中的插槽通过 <slot> 元素来实现。父组件在使用子组件时可以在组件标签内放置任意内容,这些内容将会被插入到子组件中相应的插槽中。如果没有提供内容,则可以在子组件中使用默认的内容

<!-- 子组件 -->
<template>
<div>
    <!-- 使用名为 default 的插槽,显示父组件传入的内容,如果没有内容,则显示默认文本 -->
    <slot>Default Content</slot>
</div>
</template>
<!-- 父组件-->
<template>
<div>
    <!-- 在组件标签内插入内容,这些内容将会被传递到子组件的插槽中 -->
    <ChildComponent>
    <!-- 这里的内容将会被插入到子组件的 default 插槽中 -->
    <p>This is inserted into the default slot</p>
    </ChildComponent>
</div>
</template>

<script>
import ChildComponent from './ChildComponent.vue';
export default {
    components: {
        ChildComponent
    }
};
</script>

5、Vue 中的路由是什么?如何配置和使用路由

  • 在 Vue 中,路由(Router)是用来管理单页面应用(SPA)中不同视图之间导航的工具。Vue 官方提供了 Vue Router,它是 Vue 的官方路由管理器,用于实现页面之间的跳转参数传递路由拦截等功能。

  • Vue Router 提供了以下主要功能:

    • 路由映射:将 URL 和组件映射到指定视图

    • 导航守卫:允许在路由跳转前后进行拦截处理,例如进行身份验证页面访问权限控制等。

    • 路由参数:支持动态路由参数,可以在 URL 中传递参数,并在组件中通过 $route.params 访问。

    • 嵌套路由:支持嵌套路由,可以在一个路由下定义子路由,实现组件的嵌套结构

    • 编程式导航:提供了一些方法来实现页面的编程式导航,例如 router.push()router.replace() 等。

    • 命名路由:允许给路由起一个名称,便于在代码中进行引用跳转

6、vue2的双向数据绑定原理

  • 数据劫持(Object.defineProperty)

    • 在 Vue 中,当你定义一个 Vue 实例的数据对象时,Vue 将遍历这个对象的属性,使用 Object.defineProperty() 把这些属性全部转为 getter/setter。这样一来,无论是获取还是修改这些属性,都会触发相应的 getter/setter 方法
  • 发布/订阅模式

    • Vue 中的数据绑定采用了发布/订阅模式。当数据发生变化时,会触发对应属性的 setter 方法,然后通过发布者发布一个通知,告诉所有订阅者数据已经发生改变。在 Vue 中,Watcher 充当了订阅者的角色,它会监听数据的变化,一旦数据发生改变,就会通知对应的视图更新
  • 通过结合以上两点,当数据发生改变时,Vue 能够监听到数据的变化,并且自动更新视图,实现了双向数据绑定的效果。

7、Vue 3 中双向数据绑定原理

  • Proxy

    • Vue 3 使用了 JavaScript 的 Proxy 对象,来拦截对象的操作,包括属性读取get)和设置set)。当访问修改对象的属性时,Proxy 可以捕获这些操作,从而在属性被访问修改执行相应的操作
  • Reactive(响应式)

    • 在 Vue 3 中,通过调用 reactive 函数将一个普通 JS 对象转换为响应式对象。这个函数会使用 Proxy拦截对象的操作,从而实现对象的响应式追踪
  • Effect(副作用)

    • 在 Vue 3 中,通过调用 effect 函数创建一个响应式的副作用。当副作用中使用了响应式对象的属性时,Vue 3 会自动追踪这些依赖,并在依赖发生变化时重新运行副作用。
  • 通过上述机制,Vue 3 实现了基于 Proxy 的响应式系统,从而实现了双向数据绑定。当数据发生变化时,Vue 3 能够自动追踪这些变化,并更新相关的视图,实现了双向数据绑定的效果。

8、vue的整个渲染流程

  • 初始化: Vue 应用程序的初始化阶段包括创建 Vue 实例、解析模板、初始化数据、编译模板等。在这个阶段,Vue 会对模板进行编译,生成渲染函数。

  • 响应式数据侦测: Vue 使用响应式数据系统来跟踪依赖关系,并在数据发生变化时触发重新渲染。在初始化阶段,Vue 会对组件中的响应式数据进行侦测,建立数据与视图之间的关联关系。

  • 渲染函数执行: 当数据发生变化或者组件被创建时,Vue 会执行渲染函数,生成 Virtual DOM。渲染函数的执行会根据模板中的指令、插值表达式等内容,生成 Virtual DOM 对象。

  • Virtual DOM 的 diff: Vue 使用 Virtual DOM 来描述真实 DOM 结构,并通过 diff 算法比较新旧 Virtual DOM,找出需要更新的部分。

  • 更新视图: 在 diff 算法的作用下,Vue 将根据变化的数据更新视图。Vue 会尽可能地复用已存在的 DOM 元素,只更新发生变化的部分,从而提高性能。

  • 生成真实 DOM: Vue 根据 Virtual DOM 的变化,生成真实 DOM,并将其插入到页面中。这个阶段包括创建新的 DOM 元素、删除不再需要的元素、更新发生变化的元素等操作。

  • DOM 更新完成: 当所有的变化都应用到了真实 DOM 上,视图更新完成。此时,Vue 可以监听到 DOM 更新完成的事件,并且执行相应的钩子函数或者触发事件。

9、解释 Vue 的计算属性和侦听器的区别以及适用场景。

  • Vue 中的计算属性(Computed Properties)侦听器(Watchers)都是用来监听数据变化触发相应逻辑的工具,但它们在使用场景实现方式上有一些区别。

  • 计算属性(Computed Properties):

    • 计算属性是基于依赖进行缓存的,只有相关依赖发生变化时,才会重新计算计算属性的值。
    • 计算属性的响应式的,当依赖发生变化时,计算属性会自动更新,并且会缓存计算结果,直到相关依赖发生变化时才会重新计算
    • 计算属性适用于依赖于其他数据复杂计算,例如对数据进行过滤、排序、格式化等操作。
    • 计算属性的 getter 函数只有在相关依赖发生变化时才会重新执行,而且只有在依赖发生变化时才会更新页面
  • 侦听器(Watchers):

    • 侦听器是通过监听数据变化来执行自定义逻辑的函数。
    • 侦听器适用于需要执行异步操作复杂逻辑的场景,例如监听某个数据的变化然后发送 AJAX 请求
    • 侦听器没有缓存机制,每次数据变化都会触发侦听器中的函数执行不会对执行结果进行缓存
    • 侦听器提供了更大的灵活性,可以监听任意数据的变化,并执行任意逻辑。
  • 适用场景示例:

    • 使用计算属性:当需要根据其他数据计算出一个新的值时,且这个值依赖的数据可能会发生变化,但是计算的逻辑是同步的,不需要等待异步操作完成时。
    • 使用侦听器:当需要在数据变化时执行异步操作、或者需要执行复杂的逻辑处理数据变化时,可以使用侦听器。例如监听输入框的变化,然后发送 AJAX 请求获取相关数据。

10、什么是 Vuex?它解决了什么问题?如何在 Vue 中使用 Vuex 进行状态管理?

  • Vuex 是 Vue 的官方状态管理库,用于集中式存储管理应用的所有组件的状态。Vuex 提供了一种统一的方式来管理应用的状态,并提供了一些工具和模式来解决状态管理中的一些常见问题,例如数据共享、状态持久化、状态变更追踪调试等。

  • Vuex 主要解决以下问题:

    • 集中式状态管理:当应用的状态变得复杂多个组件共享同一状态时,通过将状态集中存储在一个单一的地方(即 Store)来简化状态管理。
    • 组件间通信:通过 Store 中的状态来进行组件之间的通信,避免了组件之间通过 props事件进行传递数据的复杂性
    • 状态持久化:Vuex 提供了一种机制来将应用状态持久化本地存储(如 localStorage),以便在页面刷新后仍然可以恢复之前的状态。
    • 状态变更的追踪和调试:Vuex 提供了一些工具插件追踪状态的变化,并提供了一些调试工具来帮助开发者更容易地调试应用中的状态变更问题。
  • Vuex的使用案例

    // 在应用中创建一个 Vuex 的 Store 实例,用来存储应用的状态。
    // store.js
    
    import Vue from 'vue';
    import Vuex from 'vuex';
    
    Vue.use(Vuex);
    
    export default new Vuex.Store({
    state: {
        count: 0
    },
    mutations: {
        increment(state) {
        state.count++;
        }
    },
    actions: {
        incrementAsync(context) {
        setTimeout(() => {
            context.commit('increment');
        }, 1000);
        }
    }
    });
    
    
    // 在根组件中将创建的 Store 实例注入到 Vue 应用中。
    // main.js
    
    import Vue from 'vue';
    import App from './App.vue';
    import store from './store';
    
    new Vue({
    el: '#app',
    store, // 注入 Vuex Store
    render: h => h(App)
    });
    
    
    //在需要使用状态管理的组件中,可以通过 Vuex 提供的一些辅助函数(如 mapState、mapMutations、mapActions 等)来访问 Store 中的状态、提交 mutation 或者调用 action。
    <!-- Counter.vue -->
    
    <template>
    <div>
        <p>Count: {{ count }}</p>
        <button @click="increment">Increment</button>
        <button @click="incrementAsync">Increment Async</button>
    </div>
    </template>
    
    <script>
    import { mapState, mapActions } from 'vuex';
    
    export default {
    computed: {
        ...mapState(['count'])
    },
    methods: {
        ...mapActions(['incrementAsync'])
    }
    }
    </script>
    
    

11、vuex中actions和mutations的区别

  • 在 Vuex 中,actions 和 mutations 是用来管理状态的两个重要概念,它们之间有以下几点区别:
    • 改变状态的方式
      • mutations 用于修改 Vuex 中的状态(state),但是只能进行同步操作。
      • actions 也可以用于修改状态,但是它可以包含任意异步操作,例如调用 API、异步请求等。
    • 处理异步操作
      • mutations 不应该包含异步操作,因为它们需要立即改变状态。
      • actions 可以包含异步操作,因此在需要进行异步操作时,应该使用 actions。
    • 调用方式
      • 要触发 mutations 中的方法,你可以通过 commit 方法来调用,例如 commit('mutationName', payload)。
      • 要触发 actions 中的方法,你可以通过 dispatch 方法来调用,例如 dispatch('actionName', payload)。
    • 处理逻辑复杂性
      • 由于 mutations 只能进行同步操作,因此它们更适合用于处理简单的状态变更逻辑。
      • actions 更适合用于处理复杂的业务逻辑,例如处理异步操作、多个 mutations 之间的顺序调用等。

12、什么是 mixin?如何在 Vue 中使用 mixin

  • 在 Vue 中,Mixin 是一种可重用的 Vue 组件选项对象,它可以包含任意组件选项,例如 data、methods、computed、生命周期钩子等。Mixin 允许开发者将一组组件选项合并到多个组件中,从而实现代码的复用和组件间的共享逻辑。

  • Mixin 的主要作用是提供一种机制来组织和共享 Vue 组件中的代码,并帮助开发者避免代码重复。通过将通用的逻辑提取到 Mixin 中,可以使得组件更加简洁、可维护,并提高代码的复用性。

25、什么是 Vue 的虚拟 DOM?它的工作原理是什么?

  • Vue 的虚拟 DOM(Virtual DOM)是 Vue 中的一个核心概念,它是一个轻量级的 JavaScript 对象树,用来描述真实 DOM 树的结构。虚拟 DOM 使得 Vue 可以在内存中对 DOM 结构进行操作,而不必直接操作浏览器中的 DOM,从而提高了页面渲染的效率和性能。

13、Vue3 的特性和优势

  • Composition API(组合式 API): 引入了 Composition API,允许将一个组件的逻辑按照功能进行组合封装,而不是按照选项分散不同生命周期函数中。这种方式更灵活可读性更强,便于复用和维护。

  • 更小的体积: Vue 3 的体积比 Vue 2 更小,性能更好

  • TypeScript 支持: Vue 3 更加友好地支持 TypeScript

  • 渐进式升级: Vue 3 提供了一个渐进式升级的方案。v2升级到v3不需要一次性进行全面的更新

14、Vue3 的 Composition API 和 Options API 的区别和优缺点?

  • Options API 的优点:
    • 熟悉和易用:Vue 2 中的传统方式,开发者已经熟悉,并且在小型项目中使用较为方便。
    • 模板逻辑和组件选项一一对应,适合简单的业务逻辑和小型组件。
  • Options API 的缺点:
    • 逻辑可能分散:在大型组件中,逻辑可能分散在不同的选项中,导致代码难以维护和理解。
    • 难以复用和组合:随着组件复杂度的增加,复用和组合逻辑变得困难,代码冗余度增加。
  • Composition API 的优点:
    • 更灵活和清晰:允许按照功能来组织代码,逻辑更加清晰,更容易进行复用和组合。
    • 更好的代码组织和抽象:可以将相关逻辑聚合在一起,提高了代码的可维护性和可读性。
    • 更好的 TypeScript 支持:对 TypeScript 的支持更加友好,提供了更好的类型推断和编辑器支持。
  • Composition API 的缺点:
    • 学习曲线较高:对于之前只使用 Options API 的开发者来说,需要学习和适应新的 API。
    • 在小型项目中可能过度设计:对于简单的业务逻辑和小型组件,使用 Composition API 可能会显得过度设计。

15、Vue3 的响应式原理

  • Vue 3 的响应式原理主要基于 ES6 的 Proxy 对象和 Reflect API 实现。下面是 Vue 3 的响应式原理的基本步骤:
    • 初始化: 当创建一个响应式对象时,Vue 3 会通过递归遍历对象属性并使用 Proxy 对象进行代理
    • 侦听器注册: Vue 3 使用侦听器(watcher)来跟踪对象属性的变化。当对象属性被读取时,侦听器会将当前的依赖关系添加依赖追踪器中。
    • 属性访问: 当访问响应式对象的属性时,会触发 Proxy 对象的 get 拦截器。在这个拦截器中,Vue 3 会收集当前属性的依赖关系,并将当前的依赖关系添加到依赖追踪器中。
    • 属性修改: 当修改响应式对象的属性时,会触发 Proxy 对象的 set 拦截器。在这个拦截器中,Vue 3 会通知依赖追踪器,使得所有依赖于该属性的侦听器重新计算
    • 触发更新: 侦听器重新计算后,会将新的值传递给对应的订阅者如视图组件),从而触发视图的更新
    • 依赖追踪: Vue 3 使用依赖追踪器来追踪属性侦听器之间的依赖关系。当属性被访问时,依赖追踪器会将当前的侦听器属性关联起来,从而建立依赖关系

16、ref 和 reactive的区别

  • 返回值类型:

    • ref 函数创建的是一个包装对象,通过 .value 属性来访问修改内部的值。

    • reactive 函数创建的是一个普通的 JavaScript 对象,内部的属性都是响应式的。

  • 使用场景:

    • ref 主要用于创建单个基本类型响应式数据,比如数字字符串等。

    • reactive 主要用于创建包含多个属性复杂对象,比如对象、数组等。

  • 引用透明性:

    • 使用 ref 创建的响应式数据,需要通过 .value 属性来访问修改值,这会在代码中引入一些额外访问修改成本,但也能更清晰地表达出数据是响应式的。

    • 使用 reactive 创建的响应式对象,可以直接访问修改对象的属性,不需要额外.value 属性,但有时候可能会隐式地修改数据,导致代码不够明确

  • 性能影响:

    • 对于简单的数据类型,ref 的性能可能比 reactive 更好,因为它创建的是一个原始类型的包装对象,而不是一个普通的对象

    • 对于复杂的对象,ref 可能会产生更多的包装对象,而 reactive 创建的对象是一个普通的对象性能更稳定

17、Vue3 中的 Teleport 和 Suspense 的使用场景

  • 在 Vue 3 中,TeleportSuspense 是两个新的特性,它们分别用于处理组件的挂载位置异步组件的加载状态

  • Teleport 用于在组件内部将其子节点挂载到 DOM 树其他位置,而不是在组件的当前位置。这对于创建模态框对话框通知栏等需要在页面的不同位置显示的组件非常有用。

    <template>
      <Teleport to="body">
        <Modal />
      </Teleport>
    </template> 
    
  • Suspense 用于处理异步组件加载状态,可以在异步组件加载时显示指定的占位符(placeholder),直到异步组件加载完成后再显示真正的内容。这对于处理懒加载代码分割异步加载场景非常有用。

    <template>
      <Suspense>
        <template #default>
          <AsyncComponent />
        </template>
        <template #fallback>
          <LoadingSpinner />
        </template>
      </Suspense>
    </template> 
    

18、Pinia 的作用和优势。

  • 状态管理: Pinia 提供了一个简单而强大的方式来管理应用程序的状态。你可以将应用中的各种数据存储Pinia 的状态存储中,并在组件中轻松地访问修改这些状态。

  • 响应式: Pinia 中的状态是响应式的,这意味着当状态发生变化时相关的组件会自动更新反映最新的状态。这使得在 Vue 应用中实现数据驱动的 UI 变得更加容易

  • 适用于大型应用: Pinia 的设计使其非常适用于大型应用程序。它支持模块化分布式状态管理,可以轻松地将应用程序的状态拆分成多个模块,并将其分布到不同的组件中。

  • TypeScript 支持: Pinia 提供了完整的 TypeScript 类型支持,包括类型推断类型安全状态访问。这使得在使用 TypeScript 的 Vue 项目中更容易进行类型检查代码提示

  • 插件化架构: Pinia 具有插件化的架构,允许开发人员通过插件来扩展其功能。你可以使用现有的插件来增强 Pinia 的功能,或者编写自己的插件来满足特定的需求。

  • 轻量级和高性能: Pinia 是一个轻量级的库,体积小而且性能高效。它的设计优化了状态的访问更新过程,使得应用程序可以快速响应用户的操作。

19、与其他状态管理库相比,Pinia 有什么优势?

  • Pinia 是为 Vue 3 设计的,因此能够充分利用 Vue 3 的新特性,比如 Composition API。它还具有简单、直观的 API,支持 TypeScript,并且在性能方面表现良好。此外,Pinia 支持模块化,使得状态的组织和管理更加灵活。

20、如何在 Vue 3 项目中安装和使用 Pinia?

  • 在 Vue 3 项目中,你可以使用 npm 或 yarn 安装 Pinia。安装完成后,可以通过 createPinia() 方法创建一个 Pinia 实例,并在 Vue 应用程序的根组件中进行配置。

21、如何在组件中使用 Pinia 进行状态管理?

  • 在组件中使用 Pinia,你首先需要在组件中导入 Pinia 实例,并使用 useStore() 函数获取一个状态存储实例。然后,你可以通过该实例来访问和修改状态。

22、如何在 Pinia 中处理异步逻辑?

  • 在 Pinia 中处理异步逻辑,你可以使用 useStore() 返回的状态存储实例中提供的 actions 对象。在 actions 对象中,你可以定义异步操作的方法,并在组件中调用这些方法来执行异步逻辑。

23、Pinia 的原理是什么?

  • Pinia 的核心原理是基于 Vue 3 的响应式系统实现的。它使用 Vue 3 提供的响应式 API 来管理状态,并利用 Composition API 来组织和处理状态逻辑。同时,Pinia 还利用了 Vue 3 的模块化特性,使得状态的组织和管理更加灵活和可扩展。

24、pinia的使用案例

  • 创建 Pinia 实例:在你的 Vue 应用程序的入口文件中,创建一个 Pinia 实例,并将其挂载到应用程序上。
import { createApp } from 'vue'
import { createPinia } from 'pinia'
import App from './App.vue'

const app = createApp(App)
const pinia = createPinia()

app.use(pinia)
app.mount('#app')
  • 定义状态存储:创建一个状态存储模块,包含应用程序的状态和相关操作。
import { defineStore } from 'pinia'

export const useCounterStore = defineStore({
  id: 'counter',
  state: () => ({
    count: 0,
  }),
  actions: {
    increment() {
      this.count++
    },
    decrement() {
      this.count--
    },
  },
})
  • 在组件中使用状态存储:在组件中使用 useStore 函数来获取状态存储实例,并使用状态和操作。
<template>
  <div>
    <p>Count: {{ count }}</p>
    <button @click="increment">Increment</button>
    <button @click="decrement">Decrement</button>
  </div>
</template>

<script>
import { useStore } from 'pinia'
import { useCounterStore } from './store'

export default {
  setup() {
    const counterStore = useStore(useCounterStore)

    return {
      count: counterStore.count,
      increment: counterStore.increment,
      decrement: counterStore.decrement,
    }
  },
}
</script>

25、vuex 和 pinia 的区别

1、设计理念与灵活性

  • Vuex

    • 单一状态树:Vuex 使用单一状态树来管理所有的应用状态,这意味着所有状态都存储在一个对象中。

    • 模块化:Vuex 支持模块化,允许你将状态、getters、actions 和 mutations 组织在不同的模块中,但模块依然在单一状态树中。

  • Pinia

    • 多 Store:Pinia 支持多个 Store,每个 Store 独立管理其状态。这使得状态管理更加灵活,可以按需创建和使用 Store。
    • 更接近 Composition API:Pinia 的设计和 API 更接近 Vue 3 的 Composition API,使用起来更直观和现代。

2. 使用方式

  • Vuex

    • 配置式 API:Vuex 使用配置对象来定义 state、getters、mutations 和 actions。
    • 严格模式:Vuex 通过 mutations 修改状态,这种严格模式有助于追踪状态的变化。
  • Pinia

    • 组合式 API:Pinia 使用组合式 API 来定义 state、getters 和 actions,更符合 Vue 3 的风格。
    • 无强制 mutations:Pinia 不强制要求使用 mutations 来修改状态,可以直接在 actions 中修改状态。

3. DevTools、TypeScript 的支持,性能问题

  • Vuex

    • DevTools支持:Vuex 在 Vue DevTools 中有非常成熟的集成,支持时间旅行、状态快照和热重载等功能。

    • TypeScript支持:Vuex 支持 TypeScript,但需要额外的类型定义和配置,可能会比较复杂。

    • 性能:Vuex 的性能一般来说已经足够满足大多数应用的需求,但由于其单一状态树的设计,在极大规模的应用中可能会遇到瓶颈。

  • Pinia

    • DevTools支持:Pinia 也集成了 Vue DevTools,并提供了类似的调试功能,包括时间旅行和状态快照。此外,Pinia 在 DevTools 中的显示更直观。

    • TypeScript支持:Pinia 从设计上更好地支持 TypeScript,提供了类型安全的状态管理,使用起来更加方便。

    • 性能:Pinia 的多 Store 设计在性能上更具优势,特别是在大型应用中,能够有效分离状态管理,减少不必要的状态更新。

26、为什么 vuex 的异步操做需要在 actions 上操做,而pinia可以直接写呢?

  • 这种区别源于它们各自的设计哲学和 API 风格。

  • 在 Vuex 中,状态管理严格遵循一个明确的流程,以确保状态变化的可预测性和可追踪性。Vuex 将状态管理分为四个部分:

    • State:存储数据。
    • Getters:用于派生状态。
    • Mutations:同步地修改状态。
    • Actions:处理异步操作,并提交 mutations。
  • Pinia 则采取了一种更现代、更灵活的设计。Pinia 的设计更符合 Vue 3 的 Composition API 风格,允许直接在 actions 中进行状态修改,无需通过 mutations。这种设计简化了代码的编写,使得状态管理更直接和灵活。

27、为什么 Vuex 需要 Actions?

  • 状态管理的可预测性:Vuex 通过强制将状态修改放在 mutations 中,确保所有状态修改都是同步的。这样可以很容易地追踪状态变化的每一步,并在开发工具中进行调试和时间旅行。

  • 时间旅行调试:由于 mutations 是同步的,每个 mutations 的调用都会立即生效并记录下来,这使得 Vuex DevTools 能够进行时间旅行调试,查看每一步的状态变化。

  • 严格模式:Vuex 的严格模式会确保所有状态修改都必须通过 mutations 完成,否则会抛出错误。这种机制有助于防止在异步操作中直接修改状态,避免状态变更的不可预测性。

28、为什么 Pinia 可以直接在 Actions 中修改状态?

  • 简化 API:Pinia 的设计更加简洁和直观,不再区分 mutations 和 actions,使得状态管理代码更少,更易于理解和维护。

  • 符合 Composition API 风格:Pinia 更加符合 Vue 3 的 Composition API 风格,允许直接在 actions 中进行异步操作和状态修改,使得代码更具可读性。

  • 灵活性和现代化:Pinia 的这种设计提供了更高的灵活性,开发者可以直接在 actions 中处理异步操作并修改状态,而不需要通过额外的 mutations。