一、安装引入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>