IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> Pinia 上手指南 -- 新一代状态管理工具,它会成为 Vuex 的良好替代品吗? -> 正文阅读

[JavaScript知识库]Pinia 上手指南 -- 新一代状态管理工具,它会成为 Vuex 的良好替代品吗?

目录

一、简介

二、入门

1、安装

2、何为 Store ?

3、何时使用 Store ?

三、基本使用

1、Store

2、State?

定义 state

获取 state

重置 state

更换 state

修改 state

订阅(监听)state?

3、Getters

创建 getters

使用其他 getters

访问其他 store 中的 getters

4、Actions

创建 actions

异步 actions

访问其他 store 中的 actions

订阅 actions

四、与 Vuex 的比较

1、优缺点

Vuex 的优点

Vuex 的缺点

Pinia 的优点

Pinia 的缺点

2、使用场景

五、总结


一、简介

Pinia 是 Vue 的存储库,它允许你跨组件/页面共享状态。如果你熟悉 Composition API,你可能已经使用过简单的export const state = reactive({}),?这对于单页应用程序来说是正确的,但如果它是服务器端呈现的,则会将你的应用程序暴露给安全漏洞

即使在小型单页应用程序中,你也可以从使用 Pinia 中获得很多好处:

  • 开发工具支持
    • 跟踪动作、突变的时间表
    • store只出现在使用它们的组件中
    • 时间旅行和更容易的调试
  • 热模块更新
    • 在不重新加载页面的情况下修改你的store
    • 在开发时保持任何现有状态
  • 插件:使用插件扩展 Pinia 功能
  • 为 JS 用户提供适当的 TypeScript 支持或自动完成功能
  • 服务器端渲染(SSR)支持

?Pinia 有以下特点:

  • 完整的 TypeScript 的支持;

  • 足够轻量,压缩后的体积约2kb;

  • 去除 mutations,只有 state,getters,actions;

  • actions 支持同步和异步;

  • 没有模块嵌套,只有 store 的概念,store 之间可以自由使用,更好的代码分割;

  • 无需手动添加 store,store 一旦创建便会自动添加;?

二、入门

1、安装

yarn add pinia
// or with npm
npm install pinia

注意:

如果你的应用使用 Vue2,你还需要安装composition api:@vue/composition-api;如果你使用 Nuxt,则应遵循这些说明;如果你使用的是 Vue CLI,你可以试试这个非官方的插件。

2、何为 Store ?

一个 Store(如 Pinia)是一个实体,它持有未绑定到你的组件树的状态和业务逻辑。换句话说,它托管全局状态。它有点像一个始终存在并且每个人都可以读取和写入的组件。它包含三个概念stategetters?和?actions,并且可以假设这些概念等同与 data、computed 和 methods 在组件中。

3、何时使用 Store ?

Store 应该包含可以在整个应用程序中访问的数据。这包括在许多地方使用的数据,例如在导航栏中显示的用户信息,以及需要通过页面保存的数据,如非常复杂的多步骤表单。

另一方面,你应该避免在 Store 中包含可能托管在组件中的本地数据,例如页面本地元素的可见性。并非所有应用程序都需要访问全局状态,但如果你需要,Pania 将使你能更轻松地完成。

三、基本使用

1、Store

在 main.js 中创建并使用

import { createApp } from 'vue';
import App from './App.vue';
import { createPinia } from 'pinia';

const app = createApp(App);
const pinia = createPinia();
app.use(pinia).mount('#app');

2、State?

定义 state

在 src/pinia?下面创建一个 count.js

import { defineStore } from 'pinia'

export const useStore = defineStore({
  id: 'count',   // id必填,且需要唯一
  state: () => {
    return {
      count: 0
    }
  }
})

// 另外一种方式
export const useStore = defineStore('count', {   // 将id作为第一个参数
  state: () => {
    return {
      count: 0
    }
  }
})

获取 state

<template>
  <div>
    <p>{{ countStore.count }}</p>
  </div>
</template>

<script>
import { useStore } from "../pinia/count.js";
export default {
  setup() {
    let countStore = useStore();

    return {
      countStore
    };
  }
}
</script>

也可以结合 computed 获取

let count = computed(() => countStore.count)

state 也可以使用解构,但使用解构会使其失去响应式,这时候可以用 pinia 的?storeToRefs

import { storeToRefs } from 'pinia';
let { count } = storeToRefs(countStore);

重置 state

可以通过调用 store 上的方法将 state?重置为其初始值:$reset()

let countStore = useStore();

countStore.$reset();

更换 state

可以通过将 store 中的$state属性设置为新对象来替换 store 的整个 state

let countStore = useStore();

countStore.$state = { count: 0 };

修改 state

可以如下直接修改 state

let countStore = useStore();

countStore.count++

但一般不建议这么做,而是通过 actions?去修改 state,actions 里可以直接通过 this 访问

// count.js
export const useStore = defineStore({
  id: 'count',
  state: () => {
    return {
      count: 0
    }
  },
  actions: {   // 建议通过action修改state,更符合业务逻辑
    increment() {
      this.count++
    }
  }
})
<script>
import { useStore } from "../pinia/count.js";
export default {
  setup() {
    let countStore = useStore();
    countStore.increment();   // 通过actions修改state,更符合业务逻辑

    return {
      countStore
    };
  }
}
</script>

订阅(监听)state?

可以通过$subscribe()观察 state 及其变化,类似于 Vuex 的subscribe 方法

let countStore = useStore();

countStore.$subscribe((mutation, state) => {
  console.log(mutation);
  console.log("监听count变化触发的回调,count的值为:", state.count);
  count = state.count;
});

// 可以在监听到state变化后执行某些操作

当 state 变化时,控制台打印

3、Getters

创建 getters

export const useStore = defineStore({
  id: 'count',
  state: () => {
    return {
      count: 0
    }
  },
  getters: {
    doubleCount(state) {
      return state.count * 2
    }
  }
})

使用其他 getters

大多数时候,getters 只会依赖状态,但是有时候可能需要使用其他 getters

export const useStore = defineStore({
  id: 'count',
  state: () => {
    return {
      count: 0
    }
  },
  getters: {
    doubleCount(state) {
      return state.count * 2;
    },
    doublePlusOne() {
      return this.doubleCount + 1;
    }
  }
})

可以直接在 countStore 实例上访问 getters

<template>
  <div>
    <p>{{ countStore.doubleCount }}</p>
    <p>{{ countStore.doublePlusOne }}</p>
  </div>
</template>

访问其他 store 中的 getters

import { useOtherStore } from './other-store'

export const useStore = defineStore({
  id: 'count',
  state: () => ({
    // ...
  }),
  getters: {
    otherGetter(state) {
      let otherStore = useOtherStore();
      return state.count + otherStore.data;
    },
  },
})

4、Actions

创建 actions

export const useStore = defineStore({
  id: 'count',
  state: () => {
    return {
      count: 0
    }
  },
  actions: {
    increment() {
      this.count++;
    },
    randomCount() {
      this.count = Math.round(100 * Math.random());
    }
  }
})

像 getters 一样,actions 通过完全输入(和自动完成)支持访问整个 store 实例。与它们不同的是,它可以是异步的。

异步 actions

actions 可以像写一个简单的函数一样支持 async/await 的语法,让你愉快地应付异步处理的场景

export const useStore = defineStore({
  id: 'login',
  actions: {
    async login(account, pwd) {
      let { data } = await api.login(account, pwd);
      return data;
    }
  }
})

访问其他 store 中的 actions

import { useAuthStore } from './auth-store'

export const useSettingsStore = defineStore({
  id: 'settings',
  state: () => ({
    // ...
  }),
  actions: {
    async fetchUserPreferences(preferences) {
      let authStore = useAuthStore();
      if (authStore.isAuthenticated) {
        this.preferences = await fetchPreferences();
      } else {
        throw new Error('User must be authenticated');
      }
    }
  }
})

订阅 actions

可以使用store.$onAction()观察 actions 及其结果。传递给它的回调在操作本身之前执行。after处理承诺并允许你更改操作的返回值。onError允许你阻止错误传播。这些对于在运行时跟踪错误很有用,类似于Vue 文档中的这个技巧

这是一个在运行操作之前和它们解决/拒绝之后记录的示例

// 订阅(监听)actions
  store.$onAction(
    ({
      name,   // name of the action
      store,   // store instance, same as `someStore`
      args,   // array of parameters passed to the action
      after,   // hook after the action returns or resolves
      onError,   // hook if the action throws or rejects
    }) => {      
      console.log("name:",name);
      console.log("store:",store);
      console.log("before store.count:",store.count);
      console.log("args",args);
      // this will trigger if the action succeeds and after it has fully run.
      // it waits for any returned promised
      after(() => {
        console.log("after store.count:",store.count);
      });

      // this will trigger if the action throws or returns a promise that rejects
      onError((error) => {
        console.log(error);
      });
    }
  );

当触发 actions 时,控制台打印

默认情况下,操作订阅绑定到添加它们的组件(如果 store 位于组件的 内部setup())。意思是,当组件被卸载时,它们将被自动删除。如果要在卸载组件后保留它们,请将true作为第二个参数传递来把操作订阅与当前组件分离

export default {
  setup() {
    let someStore = useSomeStore();

    // this subscription will be kept after the component is unmounted
    someStore.$onAction(callback, true)

    // ...
  },
}

四、与 Vuex 的比较

1、优缺点

Vuex 的优点

  • 支持调试功能,如时间旅行和编辑

  • 适用于大型、高复杂度的Vue.js项目

Vuex 的缺点

  • 从 Vue 3 开始,getter 的结果不会像计算属性那样缓存

  • Vuex 4有一些与类型安全相关的问题

Pinia 的优点

  • 完整的 TypeScript 支持:与在 Vuex 中添加 TypeScript 相比,添加 TypeScript 更容易

  • 极其轻巧(体积约 1KB)

  • store 的 action 被调度为常规的函数调用,而不是使用?dispatch?方法或?MapAction?辅助函数,这在 Vuex 中很常见

  • 支持多个Store

  • 支持 Vue devtools、SSR 和 webpack 代码拆分

Pinia 的缺点

  • 不支持时间旅行和编辑等调试功能

2、使用场景

由于Pinea是轻量级的,体积很小,它比较适合中小型应用。它也适用于低复杂度的Vue.js项目,因为调试功一些能,如时间旅行和编辑仍然不被支持。

将 Vuex 用于中小型 Vue.js 项目是过度的,因为它重量级的,对性能降低有很大影响。因此,Vuex 适用于大规模、高复杂度的 Vue.js 项目。

据Vue.js 核心团队成员并积极参与 Vuex 设计的 Pinia 的创建者(Eduardo San Martin Morote)所说,Pania 和 Vuex 的相似之处多于不同之处:

Pinia 试图尽可能地接近 Vuex 的理念。它的设计是为了测试 Vuex 的下一次迭代的建议,它是成功的,因为我们目前有一个开放的 RFC,用于 Vuex5,其API与 Pinea 使用的非常相似。我对这个项目的个人意图是重新设计使用全局 store 的体验,同时保持 Vue 的平易近人的理念。我保持 Pinea 的API与 Vuex 一样接近,因为它不断向前发展,使人们很容易迁移到Vuex,甚至在未来融合两个项目(在Vuex下)。?

五、总结

以上就是关于 Pinia 的一些基本介绍,Pinia 的内容远远不止这些,对于我们使用者而言,首先掌握最基本用法,然后再去深入更多的用法,如在 Pinia 中使用插件来扩展功能等。

更多内容请前往官网了解

Piniahttps://pinia.vuejs.org/欢迎大家一键三连,一起学前端,一起进步~~~

  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2022-01-25 10:29:45  更:2022-01-25 10:30:10 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 12:49:09-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码