一、安装引入pinia
1.安装
pnpm install pinia
# 或者使用 yarn
yarn add pinia
# 或者使用 npm
npm install pinia
2.在main.js里引入
import { createApp } from 'vue'
import App from './App.vue'
import { createPinia } from 'pinia'
createApp(App).use(createPinia()).mount('#app')
pinia官网
vue3官网
二、在src目录下创建 store目录
1.创建store/index.js
/*
***import.meta.glob('./modules/*.js', { eager: true }) 同步引入多个文件
storeodules 多个store仓库集合
moduleNameList 多个store暴露的仓库名称集合
*/
/*
**pinia模块化使用示例
*/
let storeodules = {};
let moduleNameList=[]
const requireModule = import.meta.glob('./modules/*.js', { eager: true })
console.log(`requireModule`, requireModule, typeof (requireModule));
//const requireModule = import.meta.glob('./modules/*.js')
Object.entries(requireModule).forEach(([fileKey, fileValue]) => {
console.log(`fileKey,fileValue`, fileKey, fileValue);
if (fileKey === './index.js') return; // 过滤掉 index.js 本身
const moduleName = fileKey.replace(/(\.\/modules\/|\.js)/g, ''); // 获取模块名(去掉前后缀)
console.log(`moduleName`, moduleName);
storeodules[moduleName] = requireModule[fileKey][moduleName];
moduleNameList.push(moduleName)
});
console.log(`storeodules, moduleNameList`, storeodules, moduleNameList);
export {storeodules, moduleNameList}
*1* import.meta.glob是vite提供的批量导入文件或者模块的方法
*2* import.meta.glob('./modules/*.js', { eager: true }) 同步导入多个文件或者模块,值为一个对象。key为文件名,value为对应文件模块
*3* import.meta.glob('./modules/*.js') 异步导入多个文件或者模块,值为一个对象。key为文件名,value为一个动态导入文件或者模块的箭头函数,函数返回值为一个Promise对象,要用。.then的方法获取值。
*4* 本文vite+vue3动态模块化导入并使用pinia使用的是:import.meta.glob('./modules/*.js', { eager: true }) 同步导入多个文件或者模块
vite官网
2.创建store/modules/useCartStore.js和store/modules/useCounterStore.js
store/modules/useCartStore.js文件
import {ref} from 'vue'
import { defineStore } from 'pinia';
export const useCartStore = defineStore('cartStore', {
state: () => ({
cart: "购物车"
}),
actions: {
cartconterFun() {
this.cart=`购物车${
Math.round(Math.random()*100)
}`
},
},
})
store/modules/useCounterStore.js文件
import {ref} from 'vue'
import { defineStore } from 'pinia';
export const useCounterStore = defineStore('counterStore', {
state: () => ({
count:0
}),
actions: {
incrementFun() {
this.count++
},
},
})
三、pinia模块化使用示例
在HelloWorld.vue组件中使用
<script setup>
/*
**pinia模块化使用示例
*/
import { storeToRefs } from 'pinia'
import { storeodules, moduleNameList } from '@/store/index'
console.log(`storeodules, moduleNameList`, storeodules, moduleNameList);
const [useCartStore, useCounterStore] = moduleNameList.map(ele => storeodules[ele]())
console.log(`useCartStore, useCounterStore`, useCartStore, useCounterStore);
//cart、count是响应式的 ref 同时通过插件添加的属性也会被提取为 ref
const { cart } = storeToRefs(useCartStore)
const { count } = storeToRefs(useCounterStore)
// 作为 action 的 increment 可以直接解构 并且会跳过所有的 action 或非响应式 (不是 ref 或 reactive) 的属性
const { cartconterFun } = useCartStore
const { incrementFun } = useCounterStore
/*
**
*/
</script>
HelloWorld.vue完整代码
<script setup>
defineProps({
msg: {
type: String,
required: true
}
})
//只需要引入@/store/index
/*
**pinia模块化使用示例
*/
import { storeToRefs } from 'pinia'
import { storeodules, moduleNameList } from '@/store/index'
console.log(`storeodules, moduleNameList`, storeodules, moduleNameList);
const [useCartStore, useCounterStore] = moduleNameList.map(ele => storeodules[ele]())
console.log(`useCartStore, useCounterStore`, useCartStore, useCounterStore);
//cart、count是响应式的 ref 同时通过插件添加的属性也会被提取为 ref
const { cart } = storeToRefs(useCartStore)
const { count } = storeToRefs(useCounterStore)
// 作为 action 的 increment 可以直接解构 并且会跳过所有的 action 或非响应式 (不是 ref 或 reactive) 的属性
const { cartconterFun } = useCartStore
const { incrementFun } = useCounterStore
/*
**
*/
</script>
<template>
<div class="greetings">
<h1 class="green">{{ msg }}</h1>
<h3>
You’ve successfully created a project with
<a href="https://vitejs.dev/" target="_blank" rel="noopener">Vite</a> +
<a href="https://vuejs.org/" target="_blank" rel="noopener">Vue 3</a>.
</h3>
</div>
<!-- 以下pinia模块化使用示例 -->
<div class="TestOutbox">
<div>
<h1>Current cart: {{ cart }}</h1>
<br>
<button @click="cartconterFun">修改</button>
</div>
<hr>
<div>
<h1>Current Count: {{ count }}</h1>
<br>
<button @click="incrementFun">增加</button>
</div>
</div>
</template>
<style lang="scss" scoped>
.greetings {
h1 {
font-weight: 500;
font-size: 2.6rem;
position: relative;
top: -10px;
text-align: center;
}
h3 {
font-size: 1.2rem;
text-align: center;
}
}
.TestOutbox {
margin-top: 60px;
hr{
margin: 50px 0;
}
}
</style>