文章目录
前言
学习过Vue2的小伙伴一定用过 Vuex,我们知道Vuex是vue中的一个集中式管理状态的插件,那么Vue3中管理状态用的什么呢?如何使用呢?本文就来阐述这个问题。
在本文末尾我将使用 Vue3+Pinia 实现的一个简易购物车案例分享了出来,“纸上得来终觉浅,绝知此事要躬行”,知识点还是要和实际操作相结合才能够实际掌握,感兴趣的小伙伴可以尝试完成,相信对你关于Vue3和pinia的掌握会有很大的提升!!!
一、什么是Pinia?
Pinia 最初是在 2019 年 11 月左右重新设计使用 Composition API 。从那时起,最初的原则仍然相同,但 Pinia 对 Vue 2 和 Vue 3 都有效,并且不需要您使用组合 API。
二、为什么要使用Pinia?
Pinia 是 Vue 的存储库,它允许您跨组件/页面共享状态。 如果您熟悉 Composition API,您可能会认为您已经可以通过一个简单的
export const state = reactive({})
. 这对于单页应用程序来说是正确的,但如果它是服务器端呈现的,会使您的应用程序暴露于安全漏洞。 但即使在小型单页应用程序中,您也可以从使用 Pinia 中获得很多好处:
- dev-tools 支持
- 跟踪动作、突变的时间线
- Store 出现在使用它们的组件中
- time travel 和 更容易的调试
- 热模块更换
- 在不重新加载页面的情况下修改您的 Store
- 在开发时保持任何现有状态
- 插件:使用插件扩展 Pinia 功能
- 为 JS 用户提供适当的 TypeScript 支持或 autocompletion
- 服务器端渲染支持
三、Pinia对比Vuex
- mutations 不再存在。他们经常被认为是 非常 冗长。他们最初带来了 devtools 集成,但这不再是问题。
- 无需创建自定义复杂包装器来支持 TypeScript,所有内容都是类型化的,并且 API 的设计方式尽可能利用 TS 类型推断。
- 不再需要注入、导入函数、调用函数、享受自动完成功能!
- 无需动态添加 Store,默认情况下它们都是动态的,您甚至都不会注意到。请注意,您仍然可以随时手动使用 Store 进行注册,但因为它是自动的,您无需担心。
- 不再有 modules 的嵌套结构。您仍然可以通过在另一个 Store 中导入和 使用 来隐式嵌套 Store,但 Pinia 通过设计提供平面结构,同时仍然支持 Store 之间的交叉组合方式。 您甚至可以拥有 Store 的循环依赖关系。
- 没有 命名空间模块。鉴于 Store 的扁平架构,“命名空间” Store 是其定义方式所固有的,您可以说所有 Store 都是命名空间的。
四、具体使用方法
1.安装
用你最喜欢的包管理器安装 pinia
:
yarn add pinia
# 或者使用 npm
npm install pinia
在main.js中引入store
import { createApp } from 'vue'
import App from './App.vue'
// 引入pinia
import { createPinia } from 'pinia'
// createApp(App).mount('#app')
// import { createPinia } from 'pinia'
// app.use(createPinia())
const app = createApp(App);
app.use(createPinia())
app.mount('#app');
2.创建一个Store
在项目根目录的 src文件夹 —— 创建store文件夹 —— 创建 index.js 文件
index.js中
main 的解释—— 这里的"main"相当于stroe中的唯一标识
// 定义一个store
import {defineStore} from 'pinia';
export const useStore = defineStore('main',{
})
在页面中的使用 —— 在相应的页面进行引入,下面以main.vue为例
// 使用store
import { useStore } from "../store/index";
五、state
大多数时候,state 是 store 的核心部分。 我们通常从定义应用程序的状态开始。 在 Pinia 中,状态被定义为返回初始状态的函数。 Pinia 在服务器端和客户端都可以工作。
index.js中state中的数据
// 定义一个store
import {defineStore} from 'pinia';
export const useStore = defineStore('main',{
// 定义一个state
state:( )=>{
return {
// 声明一个数组,用来存储每条具体的购物记录
goodsList : [
{ id: 1, title: "手机", price: 100, num: 1, checked: false },
{ id: 2, title: "平板", price: 500, num: 1, checked: false },
{ id: 3, title: "耳机", price: 200, num: 1, checked: false },
]
}
},
})
1.访问state
以在main.vue中的使用为例
使用store
// 使用store
import { useStore } from "../store/index";
const store = useStore()
使用store中的数据
哪里此时的 store 都有哪些数据呢?
2.重置状态
将state中的数据重置到初始值
使用 —— store.$reset( )
重置状态的按钮事件
// 重置按钮的点击事件 const reset = ( )=>{ store.$reset() }
如下图案例所示:
3.改变state
使用 —— store.$patch( )
改变姓名的按钮事件
const changeName = ( )=>{ store.$patch({ name: store.name = 'hhhh' } ) }
4.批量修改state
const changeName = ( )=>{
store.$patch((state)=>{
state.name = 'hhhh'
})
}
5.替换state
使用 store.$state = { name:“Tom",age:20}
六、getters
Getter 完全等同于 Store 状态的 计算值。 它们可以用
defineStore()
中的getters
属性定义。 他们接收“状态”作为第一个参数以鼓励箭头函数的使用:
1.访问getters
// getters 依赖state中的状态 getters:{ changeName(state){ return state.name = 'Taylor Swift' }, }
在页面中访问getters
onMounted(()=>{
store.changeName
})
我们在gettes中修改了getters中的值,在onMounted钩子中调用了getters中的属性,可以看到在页面加载时就已经更改了state中的属性。
2.getters传参
Getters 只是幕后的 computed 属性,因此无法向它们传递任何参数。 但是,您可以从 getter 返回一个函数以接受任何参数:
在页面中调用并传递参数:
<span>{{store.changeName(1)}}</span>
export const useStore = defineStore('main', { getters: { changeName: (state) => { return (userId) => state.users.find((user) => user.id === userId) }, }, })
3.写为普通函数可调用this
大多数时候,getter 只会依赖状态,但是,他们可能需要使用其他 getter。 正因为如此,我们可以在定义常规函数时通过
this
访问到 整个 store 的实例, 但是需要定义返回类型(在 TypeScript 中)。 这是由于 TypeScript 中的一个已知限制,并且不会影响使用箭头函数定义的 getter,也不会影响不使用this
的 getter:
4.访问其他的store中的getters
- 在当前store中引入其他的store
// 引入其他的模块 import {useOtherStore} from './other'
- 在当前store中即可调用其他模块中的store,其实pinia并无需再像vuex中进行模块化,你所建立的每一个.js文件都是一个单独的模块,你只需要在需要使用时在页面进行引入即可。
// 访问其他的store中的getter otherGetter(state){ const otherStore = useOtherStore(); return state.name + otherStore.changeHoppy; }
七、actions
Actions 相当于组件中的 methods。 它们可以使用
defineStore()
中的actions
属性定义,并且它们非常适合定义业务逻辑:
1.访问actions
例如,我在 页面中调用actions中的方法改变state中的值:
const changeHeight = ( )=>{
store.changeHeight()
}
actions:{
changeHeight(){
this.height ++
}
}
2.调用其他store中的actions
关于调用的方法与上面getters中的方法相同,在这里就不做赘述!
八、小彩蛋——购物车案例分享
地址在这儿:
总结
以上就是今日所要分享的内容,写到这里我也正好再一次的把pinia的使用复习了一遍,希望我写下的东西能够帮助到你。最后依旧祝福屏幕前的你健康快乐、平安幸福!