唯品秀前端博客

其实vue数据管理的方式特别多,比如Provide和Inject,eventBus以及vuex等等,那么在学习vue3时候我们注意到一种新的方式,那就是Pinia,Pinia.js是由Vue.js团队核心成员开发的新一代状态管理器,使用Composition Api进行重新设计的,也被视为下一代Vuex。Pinia是一个Vue的状态管理库,允许跨组件、跨页面进行全局共享状态,也由于其设计的简洁性、和对typescript的良好支持,取代Vuex指日可待

Pinia和Vuex区别

  1. pinia没有mutations,只有:state、getters、actions
  2. pinia分模块不需要modules(之前vuex分模块需要modules)
  3. TypeScript支持很好
  4. 自动化代码拆分
  5. pinia体积更小(性能更好)
  6. pinia学习成本相比较下更小

一、安装使用Pinia

1.1 安装下载

1
2
3
yarn add pinia
# or
npm install pinia

1.2 main.js引入

1
2
3
4
5
6
7
import { createApp } from "vue";
import App from "./App.vue";
import router from "./router";

import { createPinia } from 'pinia'

createApp(App).use(createPinia()).use(router).mount("#app");

1.3 根目录新建store/index.js中写入

1
2
3
4
5
6
7
8
9
10
11
import { defineStore } from 'pinia'

export const useStore = defineStore('storeId', {
  state: () => {
    return {
      counter: 0,
    }
  },
  getters:{},
  actions:{}
})

1.4 组件使用

1
2
3
4
<script setup>
import { useStore } from '../store'
const store = useStore();
</script>

二、State

2.1 Pinia定义state数据

1
2
3
4
5
6
7
8
9
10
11
12
13
import { defineStore } from 'pinia'

export const useStore = defineStore('storeId', {
  state: () => {
    return {
      counter: 0,
      name: 'Eduardo',
      isAdmin: true,
    }
  },
  getters:{},
  actions:{}
})

2.2 组件使用pinia的state数据

1
2
3
4
5
6
7
8
9
10
11
12
<template>
    <div>
        <h1>A组件</h1>
        {{ name }}
   
    </div>
</template>
<script setup>
import { useStore } from '../store'
const store = useStore();
let { name } = store;
</script>

2.3 组件修改pinia的state数据

本身pinia可以直接修改state数据,无需像vuex一样通过mutations才可以修改,但是上面写的let { name } = store;这种解构是不可以的,所以要通过storeToRefs方法结构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<template>
    <div>
        <h1>A组件</h1>
        {{ name }}
       
        <button @click='btn'>按钮</button>
    </div>
</template>
<script setup>
import { storeToRefs } from 'pinia'
import { useStore } from '../store'
const store = useStore();
let { name }  = storeToRefs(store);
const btn = ()=>{
    name.value = '123';
}
</script>

2.4 如果state数据需要批量更新

1
2
3
4
5
6
7
8
9
10
11
12
13
14
store/index.js
import { defineStore } from 'pinia'

export const useStore = defineStore('storeId', {
  state: () => {
    return {
      counter: 0,
      name: 'Eduardo',
      arr:['a','b','c']
    }
  },
  getters:{},
  actions:{}
})

组件代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
<template>
  <div>
    <h1>A组件</h1>
    {{ name }} {{ counter }} {{ arr }}

    <button @click='btn'>按钮</button>
  </div>
</template>
<script setup>
  import {
    storeToRefs
  }
  from 'pinia'
  import {
    useStore
  }
  from '../store'
  const store = useStore();
  let {
    name, counter, arr
  } = storeToRefs(store);
  const btn = () => {
    //$patch批量更新有两种写法
    //第一种
    /*
      $patch也有两种的调用方式
      第一种写法的在修改数组时,假如我只想要把 ipList 的中第2项改成‘192.168.10.222’,
      但是也需要传入整个包括所有元素的数组,这无疑增加了书写成本和风险,显然是不合理的,所以一般都推荐使用第二种传入一个函数的写法
      */

    store.$patch({
      counter: 10001,
      appList: [1, 2, 3]
    })

    // 第二种
    store.$patch(state => {
      state.counter = 10001;
      state.ipList[0] = 100;
    })
  }
</script>

pinia数据重置

1
2
3
4
5
const store = appStore()
// 重置数据
function resetData() {
store.$reset()
}

三、actions

actions就比较简单了,写入方法,比如我们可以让state中的某一个值+=,而且传入参数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
import { defineStore } from 'pinia'

export const useStore = defineStore('storeId', {
  state: () => {
    return {
      counter: 0
    }
  },
  getters:{},
  actions:{
    changeCounter( val ){
        this.counter += val;
    }
  }
})

<template>
    <div>
        <h1>A组件</h1>
        {{ counter }}
       
        <button @click='add'>10</button>
    </div>
</template>
<script setup>
import { storeToRefs } from 'pinia'
import { useStore } from '../store'
const store = useStore();
let { counter }  = storeToRefs(store);
const add = ()=>{
    store.changeCounter(10);
}
</script>

四、getters

getters和vuex的getters几乎类似,也是有缓存的机制

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
import { defineStore } from 'pinia'

export const useStore = defineStore('storeId', {
  state: () => {
    return {
      counter: 0,
    }
  },
  getters:{
    counterPar(  ){
        console.log(111);
        return this.counter + 100;
    }
  },
  actions:{}
})

<template>
    <div>
        {{ counterPar }}
        {{ counterPar }}
        {{ counterPar }}
       
        <h1>A组件</h1>
        {{ counter }}
   
    </div>
</template>
<script setup>
import { storeToRefs } from 'pinia'
import { useStore } from '../store'
const store = useStore();
let { counter, counterPar }  = storeToRefs(store);
</script>

学习更多

Pinia如何进行modules模块划分?以及Pinia如何让数据持久化存储?

本站所有文章、图片、资源等如无特殊说明或标注,均为来自互联网或者站长原创,版权归原作者所有;仅作为个人学习、研究以及欣赏!如若本站内容侵犯了原著者的合法权益,可联系我们进行处理,邮箱:343049466@qq.com
赞(0) 打赏

上一篇:

下一篇:

相关推荐

0 条评论关于"Vue3中Pinia实现数据状态管理state、getters、actions"

表情

最新评论

    暂无留言哦~~
谢谢你请我吃鸡腿*^_^*

支付宝扫一扫打赏

微信扫一扫打赏