前言

Pinia是尤雨溪强烈推荐的一款Vue状态管理工具,也被认为是下一代Vuex的替代产品。

优点

  • 去除了mutations,只有 state,getters和actions,其中actions支持了同步和异步操作
  • 不会像Vuex那样有模块嵌套,Pinia只有store的概念,store之间可以相互使用,互不影响,达到模块扁平化的效果
  • 更好地支持ts
  • 更好地支持Vue2/Vue3
  • 逻辑更加清晰,开发起来更加简单

安装

npm i pinia

创建并挂载

1.在src目录下新建store目录并在其下面创建index.js文件,代码如下:

import { createPinia } from 'pinia'
const store = createPinia()
export default store

2.在main.js中引入store并挂载,代码如下:

import { createApp } from 'vue'
import App from './App.vue'
import store from './store/index'

createApp(App)
.use(store)
.mount('#app')

创建store

在src/store文件夹下创建一个js文件,命名按照需求即可,我这边定义为main.js,代码如下:

import { defineStore } from 'pinia'
export const mainStore = defineStore('main', {
    state: () => {
        return {
            msg: 'hello',
            count: 1
        }
    },
    actions: {},
    getters: {}
})

其中defineStore的第一个参数为该store的名称,第二个参数为一个对象,包含了该store的state,getters和actions,state改为了函数形式,目的应该是像Vue2 options API中的data类似,避免多个store中定义的属性相互受到影响。

使用store

此处使用Vue3的SFC语法,主要是Pinia更适合Vue3这种组合式API风格,方便演示

回显与修改state

<script lang="ts" setup>
    import { mainStore } from '../store/main'
    import { storeToRefs } from 'pinia'

    const store = mainStore()
    const { count } = storeToRefs(store)
    
    // 单条数据直接修改
    const handleAddCount = () => {
        store.count  
    }
</script>

<template>
    <div>
        <p>{{ store.msg }}</p>
        <p>{{ count }}</p>
        <button @click="handleAddCount"> </button>
    </div>
</template>
  • 使用方法与Vuex基本类似,要使用哪个store,就直接进行引入,非常方便,没那么多层级引用
  • 其中,我们使用了Pinia中的storeToRefs方法,此方法能够直接解构出该store的state中的某个值,并且是响应式的;如果我们直接从state上解构,那么解构出的值就不是响应式的了。
  • 如果我们要修改state中的值,不能直接去修改解构出的值,得去修改state上对应的属性

使用$patch对多条数据直接修改

使用$patch的方式对数据进行修改,可以加快修改速度,性能更好。$patch 方法可以接受两种类型的参数,对象型和回调函数型。

$patch 对象

$patch 函数  注:使用回调函数型时,回调接收一个state参数,state指代的就是对应store中的state

使用方式如下:

<script lang="ts" setup>
    import { mainStore } from '../store/main'
    import { storeToRefs } from 'pinia'

    const store = mainStore()
    const { count } = storeToRefs(store)
    
    // 使用$patch   对象
    const updateWithObj = () => {
        store.$patch({
            msg: store.msg === 'hello' ? 'hello world' : 'hello',
            count: store.count   2
        })
    }
    // 使用$patch   回调
    const updateWithFun = () => {
        store.$patch((state) => {
            state.msg = state.msg === 'hello' ? 'hello world' : 'hello'
            state.count = state.count   3
        })
    }
</script>

<template>
    <div>
        <p>{{ store.msg }}</p>
        <p>{{ count }}</p>
        <button @click="updateWithObj">$patch 对象</button>
        <button @click="updateWithFun">$patch 回调</button>
    </div>
</template>

使用actions

1.在src/store/main.js的actions对象中,添加一个方法,代码如下:

import { defineStore } from 'pinia'
export const mainStore = defineStore('main', {
    state: () => {
        return {
            msg: 'hello',
            count: 1
        }
    },
    actions: {
        changeState() {
            this.count  
            this.msg = this.msg === 'hello' ? 'hello world' : 'hello'
        }
    },
    getters: {}
})

2.使用方式为:store.方法名,代码如下:

<script lang="ts" setup>
    import { mainStore } from '../store/main'
    import { storeToRefs } from 'pinia'

    const store = mainStore()
    const { count } = storeToRefs(store)
    
   // 使用action修改数据
    const onActionClick = () => {
        store.changeState()
    }
</script>

<template>
    <div>
        <p>{{ store.msg }}</p>
        <p>{{ count }}</p>
        <button @click="onActionClick">使用action</button>
    </div>
</template>

使用getters

Pinia中的getter和Vue中的计算属性类似,在获取state之前会进行处理,具有缓存性,如果值没有改变,即使多次调用,实际上也只会调用一次。

1.在src/store/main.js的getters对象中进行添加,代码如下:

import { defineStore } from 'pinia'
export const mainStore = defineStore('main', {
    state: () => {
        return {
            msg: 'hello',
            count: 1
        }
    },
    getters: {
        getState(state) {
            console.log('getState被调用了');
            
            // getter 中不仅可以传递state直接改变数据,也可以使用this来改变数据
            return `${state.msg}   ${this.count}`
        }
    }
})

2.使用方式如下:

<script lang="ts" setup>
    import { mainStore } from '../store/main'
    const store = mainStore()
</script>

<template>
    <div>
        <p>使用getter获取数据:{{ store.getState }}</p>
        <p>使用getter获取数据:{{ store.getState }}</p>
        <p>使用getter获取数据:{{ store.getState }}</p>
    </div>
</template>

我们可以看到,即使执行了三遍一样的代码,但最终还是只调用了一次。

多个store相互调用

在Pinia中,可以在一个store中import引入另外一个store,然后通过调用引入的store方法的形式,获取引入的store的状态。

1.在src/store目录下,新建一个文件.js,代码如下:

import { defineStore } from 'pinia'

export const userStore = defineStore('user', {
    state: () => {
        return {
            name: '吴同学'
        }
    }
})

2.在需要用到的store中进行引入,并通过getters的方式获取,代码如下:

import { defineStore } from 'pinia'
import { userStore } from './user'

export const mainStore = defineStore('main', {
    getters: {
        getUserState() {
            return userStore().name
        }
    }
})

数据持久化

Pinia与Vuex一样,刷新页面后,数据就会重置,有时候我们需要将数据进行持久化存储,我们可以使用pinia-plugin-persist这个插件

安装

npm i pinia-plugin-persist --save

使用

1.在src/store/index.js文件夹下,引入并使用,代码如下:

import { createPinia } from 'pinia'
import piniaPluginPersist from 'pinia-plugin-persist'

const store = createPinia()
store.use(piniaPluginPersist)

export default store

2.在对应的store里开启持久化存储

import { defineStore } from 'pinia'
import { userStore } from './user'

export const mainStore = defineStore('main', {
    state: () => {
        return {
            msg: 'hello',
            count: 1
        }
    },
    
    // 开启数据缓存
    persist: {
        enabled: true
    }
})

更新数据以后,我们就能在浏览器控制台中看到已经将数据存储到了sessionStorage中

数据默认是存在sessionStorage中的,还会以store的名称作为key。但是我们可以对其修改,并且还可以只持久化部分state中的属性,代码如下:

import { defineStore } from 'pinia'
import { userStore } from './user'

export const mainStore = defineStore('main', {
    state: () => {
        return {
            msg: 'hello',
            count: 1
        }
    },
    
    // 开启数据缓存
    persist: {
        enabled: true,
        strategies: [
            {
              key: 'mainStore', // 修改存在缓存中的key值
              storage: localStorage,    // 修改存储方式为localStorage
              paths:['msg']  // 只持久化msg,此时刷新页面msg数据会被保留,其他state将会重置
            }
        ]
    }
})

总结

Pinia就是Vuex的替代产品,相比于Vuex,Pinia更好地兼容了Vue本身,代码更加简洁,开发起来也更加便捷。以上就是关于Pinia的介绍,如果觉得对你有帮助,就请点个赞,谢谢大家!

到此这篇关于Vue新一代状态管理工具Pinia的具体使用的文章就介绍到这了,更多相关Vue状态管理工具Pinia内容请搜索Devmax以前的文章或继续浏览下面的相关文章希望大家以后多多支持Devmax!

Vue新一代状态管理工具Pinia的具体使用的更多相关文章

  1. Vue如何指定不编译的文件夹和favicon.ico

    这篇文章主要介绍了Vue如何指定不编译的文件夹和favicon.ico,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

  2. vue自定义加载指令v-loading占位图指令v-showimg

    这篇文章主要为大家介绍了vue自定义加载指令和v-loading占位图指令v-showimg的示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

  3. vue使用动画实现滚动表格效果

    这篇文章主要为大家详细介绍了vue使用动画实现滚动表格效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  4. 关于Vue 监控数组的问题

    这篇文章主要介绍了Vue 监控数组的示例,主要包括Vue 是如何追踪数据发生变化,Vue 如何更新数组以及为什么有些数组的数据变更不能被 Vue 监测到,对vue监控数组知识是面试比较常见的问题,感兴趣的朋友一起看看吧

  5. Vue子组件props从父组件接收数据并存入data

    这篇文章主要介绍了Vue子组件props从父组件接收数据并存入data的方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

  6. Vue h函数的使用详解

    本文主要介绍了Vue h函数的使用详解,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  7. VUE响应式原理的实现详解

    这篇文章主要为大家详细介绍了VUE响应式原理的实现,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助

  8. vue+Element ui实现照片墙效果

    这篇文章主要为大家详细介绍了vue+Element ui实现照片墙效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  9. vue+elemet实现表格手动合并行列

    这篇文章主要为大家详细介绍了vue+elemet实现表格手动合并行列,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  10. iview+vue实现导入EXCEL预览功能

    这篇文章主要为大家详细介绍了iview+vue实现导入EXCEL预览功能,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

随机推荐

  1. js中‘!.’是什么意思

  2. Vue如何指定不编译的文件夹和favicon.ico

    这篇文章主要介绍了Vue如何指定不编译的文件夹和favicon.ico,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

  3. 基于JavaScript编写一个图片转PDF转换器

    本文为大家介绍了一个简单的 JavaScript 项目,可以将图片转换为 PDF 文件。你可以从本地选择任何一张图片,只需点击一下即可将其转换为 PDF 文件,感兴趣的可以动手尝试一下

  4. jquery点赞功能实现代码 点个赞吧!

    点赞功能很多地方都会出现,如何实现爱心点赞功能,这篇文章主要为大家详细介绍了jquery点赞功能实现代码,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  5. AngularJs上传前预览图片的实例代码

    使用AngularJs进行开发,在项目中,经常会遇到上传图片后,需在一旁预览图片内容,怎么实现这样的功能呢?今天小编给大家分享AugularJs上传前预览图片的实现代码,需要的朋友参考下吧

  6. JavaScript面向对象编程入门教程

    这篇文章主要介绍了JavaScript面向对象编程的相关概念,例如类、对象、属性、方法等面向对象的术语,并以实例讲解各种术语的使用,非常好的一篇面向对象入门教程,其它语言也可以参考哦

  7. jQuery中的通配符选择器使用总结

    通配符在控制input标签时相当好用,这里简单进行了jQuery中的通配符选择器使用总结,需要的朋友可以参考下

  8. javascript 动态调整图片尺寸实现代码

    在自己的网站上更新文章时一个比较常见的问题是:文章插图太宽,使整个网页都变形了。如果对每个插图都先进行缩放再插入的话,太麻烦了。

  9. jquery ajaxfileupload异步上传插件

    这篇文章主要为大家详细介绍了jquery ajaxfileupload异步上传插件,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  10. React学习之受控组件与数据共享实例分析

    这篇文章主要介绍了React学习之受控组件与数据共享,结合实例形式分析了React受控组件与组件间数据共享相关原理与使用技巧,需要的朋友可以参考下

返回
顶部