pinia面试题汇总
1、pinia是什么?
在Vue3中,可以使用传统的Vuex来实现状态管理,也可以使用最新的pinia来实现状态管理,我们来看看官网如何解释pinia的:
Pinia 是 Vue 的存储库,它允许您跨组件/页面共享状态。实际上,pinia就是Vuex的升级版,官网也说过,为了尊重原作者,所以取名pinia,而没有取名Vuex,所以大家可以直接将pinia比作为Vue3的Vuex
2、为什么要使用pinia?
- Vue2和Vue3都支持,这让我们同时使用Vue2和Vue3的小伙伴都能很快上手。
- pinia中只有state、getter、action,抛弃了Vuex中的Mutation,Vuex中mutation一直都不太受小伙伴们的待见,pinia直接抛弃它了,这无疑减少了我们工作量。
- pinia中action支持同步和异步,Vuex不支持
- 良好的Typescript支持,毕竟我们Vue3都推荐使用TS来编写,这个时候使用pinia就非常合适了
- 无需再创建各个模块嵌套了,Vuex中如果数据过多,我们通常分模块来进行管理,稍显麻烦,而pinia中每个store都是独立的,互相不影响。
- 体积非常小,只有1KB左右。
- pinia支持插件来扩展自身功能。
- 支持服务端渲染
3、pinia使用
- 准备工作: 我们这里搭建一个最新的Vue3 + TS + Vite项目
shell
npm i pinia
- pinia基础使用
- main.tsts
// main.ts import { createApp } from "vue"; import App from "./App.vue"; import { createPinia } from "pinia"; const pinia = createPinia(); const app = createApp(App); app.use(pinia); app.mount("#app"); - 创建storets创建
// src/store/user.ts import { defineStore } from 'pinia' // 第一个参数是应用程序中 store 的唯一 id export const useUsersStore = defineStore('users', { // 其它配置项 })store很简单,调用pinia中的defineStore函数即可,该函数接收两个参数:name:一个字符串,必传项,该store的唯一id。options:一个对象,store的配置项,比如配置store内的数据,修改数据的方法等等。 我们可以定义任意数量的store,因为我们其实一个store就是一个函数,这也是pinia的好处之一,让我们的代码扁平化了,这和Vue3的实现思想是一样的
- 使用storehtml
<!-- src/App.vue --> <script setup lang="ts"> import { useUsersStore } from "@/store/user"; const store = useUsersStore(); console.log(store); </script> - 添加statets
export const useUsersStore = defineStore("users", { state: () => { return { name: "test", age: 20, sex: "男", }; }, }); - 读取state数据html上段代码中我们直接通过
<template> <img alt="Vue logo" src="./assets/logo.png" /> <p>姓名:{{ name }}</p> <p>年龄:{{ age }}</p> <p>性别:{{ sex }}</p> </template> <script setup lang="ts"> import { ref } from "vue"; import { useUsersStore } from "../src/store/user"; const store = useUsersStore(); const name = ref<string>(store.name); const age = ref<number>(store.age); const sex = ref<string>(store.sex); </script>store.age等方式获取到了store存储的值,但是大家有没有发现,这样比较繁琐,我们其实可以用解构的方式来获取值,使得代码更简洁一点tsimport { useUsersStore, storeToRefs } from "../src/store/user"; const store = useUsersStore(); const { name, age, sex } = storeToRefs(store); // storeToRefs获取的值是响应式的 - 修改state数据html
<template> <img alt="Vue logo" src="./assets/logo.png" /> <p>姓名:{{ name }}</p> <p>年龄:{{ age }}</p> <p>性别:{{ sex }}</p> <button @click="changeName">更改姓名</button> </template> <script setup lang="ts"> import child from './child.vue'; import { useUsersStore, storeToRefs } from "../src/store/user"; const store = useUsersStore(); const { name, age, sex } = storeToRefs(store); const changeName = () => { store.name = "张三"; console.log(store); }; </script> - 重置state
- 有时候我们修改了state数据,想要将它还原,这个时候该怎么做呢?就比如用户填写了一部分表单,突然想重置为最初始的状态。
- 此时,我们直接调用store的$reset()方法即可,继续使用我们的例子,添加一个重置按钮
ts当我们点击重置按钮时,store中的数据会变为初始状态,页面也会更新<button @click="reset">重置store</button> // 重置store const reset = () => { store.$reset(); }; - 批量更改state数据: 如果我们一次性需要修改很多条数据的话,有更加简便的方法,使用store的
$patch方法,修改app.vue代码,添加一个批量更改数据的方法ts<button @click="patchStore">批量修改数据</button> // 批量修改数据 const patchStore = () => { store.$patch({ name: "张三", age: 100, sex: "女", }); };- 有经验的小伙伴可能发现了,我们采用这种批量更改的方式似乎代价有一点大,假如我们state中有些字段无需更改,但是按照上段代码的写法,我们必须要将state中的所有字段例举出了。
- 为了解决该问题,pinia提供的$patch方法还可以接收一个回调函数,它的用法有点像我们的数组循环回调函数了。
tsstore.$patch((state) => { state.items.push({ name: 'shoes', quantity: 1 }) state.hasChanged = true }) - 直接替换整个state: pinia提供了方法让我们直接替换整个state对象,使用store的
$state方法ts上段代码会将我们提前声明的state替换为新的对象,可能这种场景用得比较少store.$state = { counter: 666, name: '张三' }
4、pinia和vuex的区别?
- 它没有
mutation,他只有state,getters,action【同步、异步】使用他来修改state数据 - 他默认也是存入内存中,如果需要使用本地存储,在配置上比
vuex麻烦一点 - 语法上比
vuex更容易理解和使用,灵活。 pinia没有modules配置,每一个独立的仓库都是definStore生成出来的state是一个对象返回一个对象和组件的data是一样的语法
前端知识库