Vuex和Pinia的区别二

一、Vuex的命名空间是什么呢?

        在 Vuex 中,命名空间是一种组织和隔离模块的机制,用于解决模块之间可能出现的命名冲突问题。通过为模块定义命名空间,可以确保模块的状态、突变器、操作和订阅者等只在特定的命名空间内有效,避免了全局命名冲突和混淆。

        在 Vuex 中,可以使用 namespaced 属性来为模块定义命名空间。当 namespaced 属性为 true时,模块将启用命名空间。

// 模块 A
const moduleA = {
  namespaced: true,
  state: {
    count: 0,
  },
  mutations: {
    increment(state) {
      state.count++;
    },
  },
  actions: {
    incrementAsync({ commit }) {
      setTimeout(() => {
        commit('increment');
      }, 1000);
    },
  },
};

// 模块 B
const moduleB = {
  namespaced: true,
  state: {
    message: 'Hello',
  },
  mutations: {
    updateMessage(state, payload) {
      state.message = payload;
    },
  },
};

// Vuex store
const store = new Vuex.Store({
  modules: {
    a: moduleA,
    b: moduleB,
  },
});

// 组件 A
export default {
  computed: {
    ...Vuex.mapState('a', ['count']),
  },
  methods: {
    ...Vuex.mapActions('a', ['incrementAsync']),
  },
};

// 组件 B
export default {
  computed: {
    ...Vuex.mapState('b', ['message']),
  },
  methods: {
    ...Vuex.mapMutations('b', ['updateMessage']),
  },
};

注:

1、我们定义了两个模块:moduleAmoduleB,并为它们启用了命名空间。在 Vuex store 中,我们将这

两个模块注册为 ab

2、在组件 A 中,我们使用 mapState 辅助函数将 a 模块的 count 状态映射到组件的计算属性中,并使

mapActions 辅助函数将 a 模块的 incrementAsync 操作映射到组件的方法中。

3、在组件 B 中,我们使用 mapState 辅助函数将 b 模块的 message 状态映射到组件的计算属性中,并

        使用 mapMutations 辅助函数将 b 模块的 updateMessage 突变器映射到组件的方法中。通过使用命名空间,我们可以明确地访问和调用指定模块的状态和突变器,避免了可能的命名冲突。

二、Pinia在定义 state的时候为什么要用函数?为什么推荐使用箭头函数?

(1)使用函数的方式是为了确保每个组件实例都有自己独立的状态对象

(2)使用函数来定义状态可以确保每个组件实例都可以获得自己的状态对象,从而避免状态的共享和交叉影响

注:因为在 Vue中,组件的 data 属性或 setup 函数中返回的对象是共享的,如果直接将状态定义为对象字面量,则所有组件实例将共享同一个状态对象,可能导致状态的交叉污染和意外修改。

(3)箭头函数没有自己的 this 上下文,而是继承父级上下文。

(4)在箭头函数中,this 关键字将指向正确的对象,而不会因为函数内部的 this 丢失而导致错误。

(5)这对于在状态的定义中使用 this 来访问其他属性或方法非常有用。

三、两种状态管理工具更新state都有什么方法?

3.1、Vuex更新state的方法

        1.使用mutations更新state

        (1)定义一个突变器,它接收状态作为参数,并在函数内部修改状态的值。

        (2)在组件中通过 $store.commit 方法提交突变器,将状态修改的责任委托给 Vuex。

// 在 Vuex 模块中定义突变器
const moduleA = {
  state: { count: 0 },
  mutations: {
    increment(state) {
      state.count++;
    },
    decrement(state) {
      state.count--;
    }
  }
};

// 在组件中提交突变器更新状态
this.$store.commit('increment');

        2.使用操作actions更新state

        (1)定义一个操作,它接收一个上下文对象(包含 $state$commit$dispatch 等方法和属性),在操作内部处理异步逻辑并通过提交突变器来更新状态。

        (2)在组件中通过 $store.dispatch 方法调用操作,触发操作的执行。

// 在 Vuex 模块中定义操作
const moduleA = {
  state: { count: 0 },
  mutations: {
    increment(state) {
      state.count++;
    }
  },
  actions: {
    asyncIncrement(context) {
      setTimeout(() => {
        context.commit('increment');
      }, 1000);
    }
  }
};

// 在组件中调用操作更新状态
this.$store.dispatch('asyncIncrement');

        3.使用替代方式更新state

        (1)直接修改法:

this.$store.state.count = 10;

        (2)插件处理状态更新:

const myPlugin = store => {
  store.subscribe((mutation, state) => {
    // 处理状态更新的逻辑
  });
};

const store = new Vuex.Store({
  // ...
  plugins: [myPlugin]
});

注:myPlugin 是一个插件函数,通过调用 store.subscribe 来订阅状态的变化,并在状态更新时执行自定义逻辑。

3.2、Pinia更新state的方法        

        1.Pinia 使用一个特殊的函数称为 store.update() 来更新状态。

## 导入 createPinia 函数并创建 Pinia 实例
import { createPinia } from 'pinia';
const pinia = createPinia();
## 定义状态和突变器(mutations):
import { defineStore } from 'pinia';

const useStore = defineStore('storeName', {
  state: () => ({
    count: 0,
  }),
  mutations: {
    increment(state) {
      state.count++;
    },
    decrement(state) {
      state.count--;
    },
  },
});
## 在组件中使用 useStore() 函数创建 store 实例,并通过 update() 方法更新状态:
import { useStore } from '@/store';

const store = useStore();

store.update((state) => {
  state.count++;
});

注:store.update() 方法是一个同步操作,用于在当前执行上下文中更新状态。

如果需要处理异步操作,可以使用 store.patch() 方法。

store.patch((state) => {
  return new Promise((resolve) => {
    setTimeout(() => {
      state.count++;
      resolve();
    }, 1000);
  });
});

四、在Composition API 中使用Vuex

(1)安装 Vuex:在项目中安装 Vuex 依赖包。

(2)创建 Vuex 的 Store 实例:创建一个 Vuex 的 Store 实例,并将其注入到应用程序中。

import { createApp } from 'vue';
import { createStore } from 'vuex';

const store = createStore({
  state() {
    return {
      count: 0,
    };
  },
  mutations: {
    increment(state) {
      state.count++;
    },
    decrement(state) {
      state.count--;
    },
  },
});

const app = createApp(App);
app.use(store);
app.mount('#app');

(3)在组件中使用 Vuex 的状态和操作:在组件中使用 useStore 函数来获取 Vuex 的 Store 实例,并使用computed 属性和 methods 方法来访问和修改状态。

import { useStore } from 'vuex';

export default {
  setup() {
    const store = useStore();

    const count = computed(() => store.state.count);

    const increment = () => store.commit('increment');
    const decrement = () => store.commit('decrement');

    return {
      count,
      increment,
      decrement,
    };
  },
};

注:由于 Composition API 的响应式系统不会自动跟踪在普通函数中对状态的修改,因此需要使用

computed 属性来确保状态的响应式更新。

五、Pinia在组件外应该怎么使用 store 呢?Piniaoptions api模式下应该怎么使用?有无辅助函数?

(1)安装 Pinia:在项目中安装 Pinia 依赖包。

(2)创建 Pinia 实例:创建一个 Pinia 实例,并将其注入到应用程序中。

import { createApp } from 'vue';
import { createPinia } from 'pinia';

const pinia = createPinia();

const app = createApp(App);
app.use(pinia);
app.mount('#app');

(3)定义状态和突变器:在组件中,可以使用 defineStore 函数定义状态和突变器。

import { defineStore } from 'pinia';

export const useStore = defineStore('storeName', {
  state: () => ({
    count: 0,
  }),
  actions: {
    increment() {
      this.count++;
    },
    decrement() {
      this.count--;
    },
  },
});

// 可选:导出用于创建 Store 实例的 Pinia 实例
export { pinia };

(4)在组件外使用和操作

方式一:在任何需要使用Store实例的地方,导入 useStore 函数并调用它,以获取全局的 Store 实例。


import { useStore } from '@/store';

const store = useStore();
console.log(store.count); // 访问状态
store.increment(); // 调用操作

方式二:在组件外使用 Store 实例之前先进行异步初始化,可以使用 pinia.use 方法,并在回调函数中进行相关初始化操作。

import { pinia } from '@/store';

pinia.use(() => {
  // 进行异步初始化操作,例如从服务器获取数据
}).then(() => {
  // 初始化完成后,可以在这里使用 Store 实例
  const store = useStore();
  console.log(store.count);
});

(5)在组件中使用状态和操作:在组件中可以使用 useStore 函数创建状态实例,并使用实例的属性和方法来访问和修改状态。

import { useStore } from '@/store';

export default {
  setup() {
    const store = useStore();
    return {
      count: computed(() => store.count),
      increment: () => store.increment(),
      decrement: () => store.decrement(),
    };
  },
};

总结:由此两个代码的对比我们可以看出使用Pinia更加的简洁,轻便。Pinia取消了原有的mutations,合并成了actions,且我们在取值的时候可以直接点到那个值,而不需要在.state,方法也是如此。

Pinia有无辅助函数

        在 Options API 模式下,没有提供像辅助函数 mapStatemapGettersmapMutationsmapActions 这样的直接辅助函数。但是你仍然可以在组件中使用 computed 属性来访问状态,并使用方法来调用操作。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值