vite+vue3动态模块化导入并使用pinia

本文详细介绍了如何在Vue3项目中使用Pinia进行状态管理,包括安装步骤、在main.js中引入和配置store,以及如何在模块化结构中创建和使用store实例。重点讲解了如何通过import.meta.glob动态导入store模块并利用storeToRefs提取响应式数据和执行actions。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

vitenode

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值