pinia初体验

2/20/2022 状态管理

目前个人来说 pinia 确实比 vuex 更好用

# 一、安装 pinia

  1. yarn create vite // 创建一个项目  vue3 + vite + ts
  2. yarn add pinia  // 2.0.11
1
2

# 二、用 pinia 的规则创建一个 store

第一步先在/src/main.ts里引入pinia

  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')

1
2
3
4
5
6
7
8
9
10

接着 和 vuex 差不多, 新建一个 store 文件夹,然后创建一个 index.ts 文件

  // 1. 定义状态容器 状态
  // 2. 修改容器中的state
  // 3. 仓库中的action的使用

  import {defineStore} from 'pinia'
  import { jswuStore } from './jswu' // 第二个容器仓库
  export const mainStore = defineStore('main', { // 创建一个名字为main的容器仓库,唯一值
    state: () => { // 用来存储全局的状态。
      return {
        hellow: 'hellow Word',
        count: 0,
        phone: '15023654578'
      }
    },
    getters: { // 用来监视或者说是计算状态的变化的,有缓存的功能。
      phoneHidden():String {
        console.log('getters调用');
        return this.phone.toString().replace(/^(\d{3})\d{4}(\d{4})$/,'$1****$2') // 实现 电话号码 隐藏
      }
      // phoneHidden:(state) => {
      //   console.log('getters调用');
      //   return state.phone.toString().replace(/^(\d{3})\d{4}(\d{4})$/,'$1****$2')
      // }
    },
    actions: { // 修改state全局状态数据的
      changeState() {
        this.count++,
        this.hellow = this.hellow === "hellow Word" ? 'sdasd' : 'hellow Word'
      },
      getList() {
        console.log(jswuStore().list)
        console.log(jswuStore().list[0])
      }
    }
  })
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

# 三、使用 pinia 里的数据

  <template>
    <div class="">{{store.hellow }}</div>
    <div>{{store.count}}</div>
    <div>{{store.phoneHidden}}</div>
    <hr/>
    <div class="">{{hellow }}</div>
    <div>{{count}}</div>
    <hr/>
    <div>{{phoneHidden}}</div>
  </template>

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

  const store = mainStore()

  const { hellow, count, phoneHidden} = storeToRefs(store)

  </script>

  <style scoped lang="scss">

  </style>

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

引入 index.ts 文件后直接使用, 想少敲点代码还可以使用storeToRefs来解构赋值,这样才会使数据具有响应性

# 四、Pinia 修改状态数据的几种方式

上面和下面这两段代码是 两个组件,自己在 components文件夹里创建后然后在 App.vue 引用就好

  <template>
    <div><button @click="handleClick">修改状态数据1</button></div>
    <div><button @click="handleClickParth">修改状态数据2-patch</button></div>
    <div><button @click="handleClickMethod">修改状态数据3-method</button></div>
    <div><button @click="handleClickActions">修改状态数据3-actions</button></div>
    <div><button @click="handleClickChangePhone">修改电话号码</button></div>
    <div><button @click="getList">获得数组</button></div>
  </template>

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

  // 第一种方式
  const handleClick = () => { // 简单地数据处理
    store.count++
  }

  // 第二种方式 $patch
  const handleClickParth = () => {
    store.$patch({
      count: store.count+2,
      hellow: store.hellow === "hellow Word" ? 'sdasd' : 'hellow Word'
    })
  }

  // 第三种方式 $patch 传递函数
  const handleClickMethod = () => {
    store.$patch( (state) => {
      state.count++
      state.hellow = state.hellow === "hellow Word" ? 'sdasd' : 'hellow Word'
    })
  }

  //  第四种方式 pinia 中actions 用法
  const handleClickActions = () => {
    store.changeState()
  }

  //
  const handleClickChangePhone = () => { // getters处理
    store.phone = "15044444444"
  }

  const getList = () => { // 另外一个容器仓库
    store.getList()
  }
  </script>

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
42
43
44
45
46
47
48
49

其中当数据更改较多使用$patch,经过优化加快了修改速度,而当数据更复杂的时候,还有一种方式是传递函数,比如数组、对象的修改。

还有一种 actions 调用函数修改数据,类似vuex,我觉得这种可以用在多处有相同操作的场景,不过值得注意的一个地方

在用 actions 的时候,不能使用箭头函数,因为箭头函数绑定是外部的 this。

# 五、Pinia 中的 Getters 使用

Pinia 中的 Getter 和 Vue 中的计算属性几乎一样,就是在获取 State 的值时作一些处理。比如我们有这样一个需求,就是在 state 里有有一个状态数据是电话号码,我们想输出的时候把中间四位展示为 ****.这时候用 getters 就是非常不错的选择。

  <template>
    <div class="">{{store.hellow }}</div>
    <div>{{store.count}}</div>
    <div>{{store.phoneHidden}}</div>
    <hr/>
    <div class="">{{hellow }}</div>
    <div>{{count}}</div>
    <hr/>
    <div>{{phoneHidden}}</div>
  </template>

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

  const store = mainStore()

  const { hellow, count, phoneHidden} = storeToRefs(store)

  </script>

  <style scoped lang="scss">

  </style>

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

phoneHidden 就是 getters 中 函数返回的新数据, 它是具有缓存性,相同数据只会执行一次,

   getters: { // 用来监视或者说是计算状态的变化的,有缓存的功能。
      phoneHidden():String {
        console.log('getters调用');
        return this.phone.toString().replace(/^(\d{3})\d{4}(\d{4})$/,'$1****$2') // 实现 电话号码 隐藏
      }
      // phoneHidden:(state) => {
      //   console.log('getters调用');
      //   return state.phone.toString().replace(/^(\d{3})\d{4}(\d{4})$/,'$1****$2')
      // }
    },
1
2
3
4
5
6
7
8
9
10

两种使用方式

上次更新: 2/21/2022, 12:33:55 AM