07-Pinia(V2)
码路教育 7/24/2022
# 一,Pinia使用
- Pinia(V2),是Vuex的下一版本,在Vue2和Vue3中都能用。
- Pinia支持多store开发,可以非常自由地组织"状态管理"的数据流逻辑。
- Pinia对Hooks编程思想非常友好,它对TS也非常友好。
- 如果你想学习更多,去看官网和社区。
# 1,第一步:安装
yarn add pinia
yarn add axios@0.27.2
1
2
2
# 2,第二步:创建并在main.ts中使用
// src/pages/student/store/useCnodeStore.ts
import { defineStore } from 'pinia'
import axios from 'axios'
// 强调:pinia要求定义store时,名称以use*开头的函数
const useCnodeStore = defineStore('cnode', {
// 这里的state,只能使用工厂函数写法
// 特点:在组件中可以被共享,并且具有响应式
state: () => {
return {
num: 1,
list: []
}
},
// 这里的getters就是计算属性,可用于计算state,还可以对另一个getters做计算
getters: {
total1 () {
return this.num * 10
},
total2 () {
return this.total1 * 2
}
},
// 这里的actions,可以直接修改state数据,无论是同步代码,还是异步代码。
actions: {
addNum (step=1) {
this.num += step
},
async getList (params) {
const res = await axios({
url: '/api/v1/topics',
method: 'GET',
params
})
if (res.status === 200) {
if (res.data && res.data.success) {
this.list = res.data.data
}
}
}
}
})
export default useCnodeStore
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
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
// main.ts
import { createApp } from 'vue'
import { createPinia } from 'pinia'
import './style.css'
import router from './router'
import App from './App.vue'
let app = createApp(App)
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import * as ElementPlusIconsVue from '@element-plus/icons-vue'
// 注册路由
app.use(router)
app.use(ElementPlus)
// 创建pinia实例,注册app.use(pinia)
const pinia = createPinia()
app.use(pinia)
app.mount('#app')
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
在添加学生模块使用之,如下:
// src/pages/student/PageB.vue
<template>
<h1>状态管理</h1>
<h1 v-text="num"></h1>
<h1 v-text="store.total1"></h1>
<h1 v-text="store.total2"></h1>
<button @click="add">自增</button>
<button @click="reset">重置</button>
<hr />
<div v-for="(row, idx) in store.list" :key="row.id">
<span v-text="idx"></span>:
<span v-text="row.title"></span>
</div>
<button @click="pageHandle(-1)">上一页</button>
<button @click="pageHandle(1)">下一页</button>
</template>
<script setup>
import useCnodeStore from "./store/useCnodeStore";
import { storeToRefs } from "pinia";
import { onMounted, watchEffect, ref } from "vue";
const page = ref(1);
// store属性解构后,响应式失效,用storeToRefs包一层
const { num } = storeToRefs(useCnodeStore());
// store属性不解构,响应式没有任何问题。
const store = useCnodeStore();
// console.log('---store', store)
const add = () => {
// 修改pinia中的state数据【OK】
// store.$patch({num: store.num + 1})
// 使用actions方法修改pinia中的state数据
store.addNum(10);
};
const reset = () => {
store.$reset();
};
watchEffect(
() => {
store.getList({ page: page.value, limit: 5, tab: "ask" });
},
{ flush: "pre" }
);
const pageHandle = (num) => {
if (page.value === 1 && num === -1) return;
page.value += num;
};
watchEffect(() => {
// 监听store的变化
store.$subscribe((mutations, state) => {
// console.log('---mutations', mutations) // 信号
// console.log('---state', state) // store最新状态
// todo something
});
});
watchEffect(() => {
// 用于计算actions方法的执行时间
store.$onAction(({ name, after }) => {
const st = Date.now();
console.log(`${name} start`, st);
after(() => {
const et = Date.now();
console.log(`${name} end`, et);
console.log(`${name} 时间差`, et - st);
});
});
});
</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
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
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
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# 二,总结
- createPinia() 用于创建pinia实例
- defineStore('storeId', { state, getters, actions }) 会定义store, 每个store都一个以use*开头的Hooks函数, state必须是工厂函数, getters不仅可以对state进行计算, 还可以另一个getters进行计算, actions不仅可以编写同步方法, 还可以编写异步逻辑.
- 怎么修改store中的state? 可以使用 $patch({})进行批量修改, 还可以调用actions方法来修改.
- 怎么重置store中的state? 使用$reset() 方法重置store.
- 如何监听store中的state的变化? 使用$subscribe((mutations, state)=>{})进行监听. 监听是一个副作用, 建议放在watchEffect中.
- 如何测量actions方法的执行时间? 使用$onAction(({name, after})=>{})
- 警告: 如果你对store进行解构, 响应式会失效, 使用 storeToRefs包裹一层即可.