pinia和vuex的区别
什么是“状态管理模式”?
const Counter = {
// 状态
data () {
return {
count: 0
}
},
// 视图
template: `
<div>{{ count }}</div>
`,
// 操作
methods: {
increment () {
this.count++
}
}
}
createApp(Counter).mount('#app')
这个状态自管理应用包含以下几个部分:
-
状态,驱动应用的数据源;
-
视图,以声明方式将状态映射到视图;
-
操作,响应在视图上的用户输入导致的状态变化
以下是一个表示“单向数据流”理念的简单示意:
但是,当我们的应用遇到多屏幕编辑 Markdown文章功能;
- 增加了 焦点写作模式、预览模式、简洁写作模式、左右区域同步滚轮设置 等功能,功能按钮位于编辑区域与预览区域中间;
- 增加了 检查列表 功能。
量架构。
vuex是采用集中式管理组件依赖的共享数据的一个工具,可以解决不同组件数据共享问题
- 修改state状态必须通过mutations
- mutations只能执行同步代码,类似ajax,定时器之类的代码不能在mutations中执行
- 执行异步代码,要通过actions,然后将数据提交给mutations才可以完成
- state的状态即共享数据可以在组件中引用
- 组件中可以调用action
pinia
Pinia 是 Vue.js 的轻量级状态管理库,它允许您跨组件/页面共享状态。最近很受欢迎。它使用 Vue 3 中的新反应系统来构建一个直观且完全类型化的状态管理库。
其实Pinia就是Vuex5,只不过为了尊重原作者的贡献就沿用了这个看起来很甜的名字Pinia。
设置
Vuex 设置
npm install vuex --save
# or npm
yarn add vuex --save
要创建store,你可以使用包含创建基本store所需的states、actions和 getter 的对象调用 createStore
方法:
import Vue from 'vue'
import { Vuex } from 'vuex'
Vue.use(Vuex)
const useStore = new Vuex.Store({
// 仓库 基本上是一个容器
state: {
todos: [
{ id: 1, text: '...', done: true },
],
count: 0
},
//类似于vue中的计算属性
getters: {
doneTodos (state) {
return state.todos.filter(todo => todo.done)
},
getCount(state, count){
state.count = count;
}
},
// 同步函数 修改state函数
mutations: {
increment (state) {
state.count++
},
setCount(state){
state.count++;
}
},
// Action 提交的是 mutation,而不是直接变更状态。
// Action 可以包含任意异步操作。
actions: {
increment (context) {
context.commit('increment')
}
},
//将store分割成模块(module),每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块——从上至下进行同样方式的分割:
modules: {
}
})
export default useStore
对于大型的项目把vuex相关代码分割到模块中
为什么Vuex要通过mutations修改state,而不能直接修改?
因为state是实时更新的,mutations无法进行异步操作,而如果直接修改state的话是能够异步操作的,当你异步对state进行操作时,还没执行完,这时候如果state已经在其他地方被修改了,这样就会导致程序存在问题了。所以state要同步操作,通过mutations的方式限制了不允许异步。
怎么保持页面刷新vuex数据不丢失?
将vuex中的数据直接保存到浏览器缓存中(sessionStorage、localStorage、cookie)
在父页面向后台请求远程数据,并且在页面刷新前将vuex的数据先保存至sessionStorage
created() {
// 判断缓存中是否有数据
if (seIuY3ore')) {
// Object.assign() 方法用于将所有可枚举属性的值从一个或多个源对象复制到目标对象。它将返回目标对象。
this.$store.replaceState(Object.assign({}, this.$store.state, JSON.parse(sessionStorage.getItem('store'))));
}
// 监听 在页面刷新时将vuex里的信息保存到sessionStorage里
window.addEventListener('beforeunload', () => {
sessionStorage.setItem('store', JSON.stringify(this.$store.state));
});
}
vuex-persistedstate插件
npm install vuex-persistedstate --save
可以选择数据存储的位置,可以是localStorage/sessionStorage/cookie,此处以存储到sessionStorage为例,配置如下:
import createPersistedState from "vuex-persistedstate"
const store = new Vuex.Store({
// ...
plugins: [createPersistedState({
storage: window.sessionStorage
})]
})
pinia设置
yarn add pinia@next
# or npm
npm install pinia@next
Pinia是一个围绕Vue 3 Composition API的封装器。
import type { App } from 'vue';
import { createPinia } from 'pinia';
const store = createPinia();
export function setupStore(app: App<Element>) {
app.use(store);
}
export { store };
为了创建一个store,你用一个包含创建一个基本store所需的states、actions和getters的对象来调用 defineStore
方法。
import en-dash, --- ivrsefinetoo e{
id: 'todo', // 唯一值
state: () => ({
count: 0,
title: "hello",
list: [1, 2, 3, 4]
}),
// 用来封装计算属性 有缓存功能 类似于computed
getters: {
getCount(): Number{
// this指向的便是store实例
return this.count;
},
getCountAdd(): string{
return this.title+ this.getCount; // 调用其它getter
}
},
// 支持同步和异步
actions: {
setCount(){
this.count++
}
}
// 数据持久化
// npm i pinia-plugin-persist
persist: {
**LaTeX** 数学表达式[here][1].
##, / 新的甘特图功能,丰富你的文章
``rmaid
gantt
//key的名称
title Adding GANTT diagram functionality to mermaid
storage: sessionStorage,
已完成 进去 :done, des1, 2014-01-06,2014-01-08
进行中 `
Pinia没有modules,如果想使用多个store,直接定义多个store传入不同的id即可,如:
` f"
p:act const storeA = defineStore("storeA", {...});
export const storeB = defineStore("storeB", {...});
export const storeC = defineStore("storeB", {...});
├── modulers
│ ├── user (具体模块,以实际项目为准)
│ │ └── index.ts (store定义)
│ │ └── types.ts (store类型)
├── index.ts (用于导出store)
**数据持久化使用pinia-plugin-persist **
export const useTodoStore = defineStore({
id: 'todo', // 唯一值
// 数据持久化
persist: {
enabled: true, // 开启缓存
strategies: [
{
// 可以自定义,不填默认是store的ID
key: 'user',
//更改默认存储,可以更改为localStorage
section 现有任务
// 可以选择哪些进入存储,这样就不用全部都进去存储了
// 默认是全部进去存储
paths: ['list']
}
]
}
})
使用
pinia使用
import { storeToRefs } from 'pinia' // 使用storeToRefs方法解构
export default defineComponent({
setup() {
const todo = useTodoStore()
// 解构 可以保证解构出来的数据也是响应式的
let { count, title} = storeToRefs(todo)
// 修改值
todo.count = 2
// 批量修改多个值
todo.$patch({
counter: store.count ++,
title: 'work',
)}
// $patch工厂函数方式
todo.$patch((state) => {
state.count = 99;
state.title = 'work'
})
// $state 缺点是必须修改整个对象
todo.$state = { count: 88, title: '修改值' }
// 使用action 修改
todo.increment()
// 重置 初始值
todo.$reset()
return {
// 只允许访问特定的state 获取
state: todo.title,
}
},
})
请注意,在访问其属性时省略了 store 的 state 对象
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QE0Ja7c6-1672971388997)(https://secure2.wostatic.cn/static/x6TFWNNQMHTcX4eRYPt55v/image.png?auth_key=1672971368-8uk7go5wrAQSEahNSKmBRd-0-a3fe237b5412b64770514076eff2c1b0)]
vuex使用
export default {
data(){
return{
count: this.$store.state.count
}
},
computed: {
count: {
get () {
return this.$store.state.count
},
set (value) {
this.$store.commit('count', value)
}
}
}
}
性能对比
Pinia和Vuex都非常快,在某些情况下,使用Pinia的web应用程序会比使用Vuex更快。这种性能的提升可以归因于Pinia的极轻的重量,Pinia体积约1KB。
尽管Pinia是在Vue devtools的支持下建立的,但由于Vue devtools没有暴露出必要的API,所以一些功能如时间旅行和编辑仍然不被支持。当开发速度和调试对你的项目来说更重要时,这是值得注意的。
优缺点
-
Vuex的优点
支持调试功能,如时间旅行和编辑(vuex执行的错操作会被记录下来,返回回退到此操作的状态)
适用于大型、高复杂度的Vue.js项目
-
Vuex的缺点
从 Vue 3 开始,getter 的结果不会像计算属性那样缓存
-
Pinia的优点
完整的 TypeScript 支持:与在 Vuex 中添加 TypeScript 相比,添加 TypeScript 更容易极其轻巧(体积约 1KB)
支持插件扩展功能
支持模块热更新无需加载页面可以修改容器,可以保持任何现有的状态
pinia中只有state、getter、action,抛弃了Vuex中的Mutation,Vuex中mutation一直都不太受小伙伴们的待见,pinia直接抛弃它了,这无疑减少了我们工作量。
action支持同步和异步
支持服务端渲染
-
Pinia的缺点
不支持时间旅行和编辑等调试功能