在线代码演示
https://stackblitz.com/github/superBiuBiuMan/pinia_registerWay
使用注意点
不能直接结构赋值
如果直接结构赋值,就像下面一样,就会失去响应式效果(数据变了,视图依旧不会更新)
< template>
{ { name } }
< / template>
const { name } = useCounterStore ( ) ;
如果确实需要解构赋值,可以使用storeToRefs
https://pinia.vuejs.org/zh/core-concepts/index.html#using-the-store
import { storeToRefs } from 'pinia'
export default defineComponent ( {
setup ( ) {
const store = useCounterStore ( )
const { name, doubleCount } = storeToRefs ( store)
const { increment } = store
return {
name,
doubleCount,
increment,
}
} ,
} )
多次使用依旧是相同的对象
const store2 = useShopInfo ( ) ;
const store3 = useShopInfo ( ) ;
console. log ( store2 === store3)
创建方式(多种)
使用store时要先把store的定义import进来,再执行定义函数使得实例化。
但是,在项目逐渐庞大起来后,每个组件要使用时候都要实例化吗?
在文中开头讲过,pinia的代码分割机制是把引用它的页面合并打包,
那像下面的例子就会有问题,user被多个页面引用,最后user store被重复打包。
方法0:官方示例写法
export default deinfStore ( 'shopInfo' , {
...
} )
import { createApp } from 'vue'
import { createPinia } from "pinia" ;
import './style.css'
import App from './App.vue'
const app = createApp ( App) ;
app. use ( createPinia ( ) )
app. mount ( '#app' )
import useShopInfo from "./store/useShopInfo.ts" ;
const store = useShopInfo ( ) ;
store. addCar ( {
name : name. value,
price : price. value
} )
先简单了解下app.use方法
我们先来了解下vue的app.use
方法,app.use
用来注册插件,插件可以是一个带 install()
方法的对象,亦或直接是一个将被用作 install()
方法的函数。插件选项 (app.use()
的第二个参数) 将会传递给插件的 install()
方法。
若 app.use()
对同一个插件多次调用,该插件只会被安装一次 。
import { createApp} from "vue" ;
const app = createApp ( ) ;
import 插件带install方法 from "./test"
import 插件不带install方法 from "./test"
app. use ( 插件带install方法) ;
app. use ( ( app, options ) => {
} )
基于app.use()
对同一个插件多次调用,该插件只会被安装一次 。我们其实可以看到很多组件库都会叫我们这样使用组件库
import TDesign from 'tdesign-vue-next' ;
import { createApp} from "vue" ;
import App from './app.vue' ;
const app = createApp ( App) ;
app. use ( TDesign) ;
import { App} from 'vue'
import {
Button,
Popup,
Avatar,
Icon,
...
} from 'tdesign-vue-next' ;
export default ( app : App) => {
app. use ( Button)
app. use ( Popup)
app. use ( Avatar)
app. use ( Icon)
app. use ( ... . )
}
现在明白了吧,我们引入的TDesign
就是一个主入口文件,他帮我们一个一个的使用了插件,从而达到了全局引入的效果,当然,你也可以自己去引入,然后按需使用插件
方法1:store统一实例化并暴露使用
我们可以使用此方法,我们在store文件夹下方的index.ts
对其他store进行统一实例化然后暴露使用
store
a. ts
b. ts
import useA from "../store/a" ;
const infoA = useA ( ) ;
console. log ( infoA. name) ;
store
a. ts
b. ts
index. ts
import appStore from "./store" ;
console. log ( appStore. infoA. name) ;
创建总路口和其他仓库
import shopInfo from "./useShopInfo"
export interface AppStore {
shopInfo : ReturnType< typeof shopInfo> ,
}
const appStore = { } as AppStore;
export const registerStore = ( ) => {
appStore. shopInfo = shopInfo ( ) ;
}
export default appStore;
import { defineStore} from "pinia"
export default defineStore ( 'shopInfo' , {
state : {
money : ''
}
} )
全局注册
import { createApp} from "vue" ;
import App from "./App.vue" ;
import { registerStore} from "./store" ;
const app = createApp ( App) ;
app. use ( createPinia) ;
registerStore ( ) ;
app. mount ( '#app' )
组件使用
import appStore from "../store" ;
< div> { { appStore. shopInfo. money } } < / div>
方法2:store统一实例化并暴露使用
这种方法不需要全局注册pinia,当然,你为了美观也可以全局注册下 原理是因为defineStore
返回值useStore
函数,这个useStore
函数第一个参数可以接收一个pinia
对象,如果有传入则使用传入的pinia
对象,如果没有传入pinia
对象,那么会去全局寻找,否则就会报错,报错内容大概如下
` [🍍]: getActivePinia was called with no active Pinia. Did you forget to install pinia?\n ` +
` \tconst pinia = createPinia()\n ` +
` \tapp.use(pinia)\n ` +
` This will fail in production. `
创建总路口和其他仓库
import { createPinia} from "pinia" ;
import UseInfo from "./user.ts" ;
import type { App } from 'vue' ;
const store = createPinia ( ) ;
export default ( app : App) => {
app. use ( store) ;
}
export const useInfo = UseInfo ( store) ;
import { defineStore} from "pinia"
export default defineStore ( 'shopInfo' , {
state : {
money : ''
}
} )
全局注册(方法2可以不全局注册)
import { createApp} from "vue" ;
import App from "./App.vue" ;
import pinia from "./store"
const bootstrap = ( ) => {
const app = createApp ( App)
app. use ( TDesignUI)
app. use ( ( app ) => {
app. use ( pinia)
} )
}
void bootstrap ( )
组件使用
import { useInfo } from "../store" ;
< div> { { useInfo. money } } < / div>
参考文章