MST

星途 面试题库

面试题:Vue Pinia Store在复杂业务逻辑中的应用

假设你正在开发一个电商应用,涉及商品列表展示、购物车管理、用户订单记录等复杂业务逻辑。请说明如何使用Pinia Store进行模块化管理,以及如何处理不同模块间的数据交互与依赖关系。
34.0万 热度难度
前端开发Vue

知识考点

AI 面试

面试题答案

一键面试

使用Pinia Store进行模块化管理

  1. 创建模块
    • 对于商品列表展示,可以创建一个productStore。例如:
import { defineStore } from 'pinia';

export const useProductStore = defineStore('product', {
    state: () => ({
        products: [],
        // 例如当前筛选条件
        filter: ''
    }),
    actions: {
        async fetchProducts() {
            // 这里进行异步请求获取商品列表
            const response = await fetch('/api/products');
            this.products = await response.json();
        },
        updateFilter(newFilter) {
            this.filter = newFilter;
        }
    }
});
- 购物车管理可创建`cartStore`:
import { defineStore } from 'pinia';

export const useCartStore = defineStore('cart', {
    state: () => ({
        items: [],
        totalPrice: 0
    }),
    actions: {
        addProductToCart(product) {
            this.items.push(product);
            this.calculateTotalPrice();
        },
        removeProductFromCart(index) {
            this.items.splice(index, 1);
            this.calculateTotalPrice();
        },
        calculateTotalPrice() {
            this.totalPrice = this.items.reduce((acc, item) => acc + item.price, 0);
        }
    }
});
- 用户订单记录创建`orderStore`:
import { defineStore } from 'pinia';

export const useOrderStore = defineStore('order', {
    state: () => ({
        orders: []
    }),
    actions: {
        async fetchOrders() {
            const response = await fetch('/api/orders');
            this.orders = await response.json();
        },
        placeOrder(cartItems) {
            // 这里处理下单逻辑,例如将cartItems转化为订单数据结构并发送请求
            // 下单成功后可清空购物车
            const newOrder = { items: cartItems, total: this.$useCartStore.totalPrice };
            this.orders.push(newOrder);
            this.$useCartStore.items = [];
            this.$useCartStore.totalPrice = 0;
        }
    }
});
  1. 注册模块:在应用入口(通常是main.js)注册这些模块:
import { createApp } from 'vue';
import { createPinia } from 'pinia';
import App from './App.vue';

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

处理不同模块间的数据交互与依赖关系

  1. 通过this.$useStore访问其他模块
    • 例如在orderStoreplaceOrder方法中,需要获取cartStore中的购物车商品和总价,就可以通过this.$useCartStore访问cartStore实例。如上述orderStoreplaceOrder方法所示。
  2. 订阅状态变化
    • 可以使用watch来监听其他模块状态变化并做出响应。例如在productStore中,如果商品列表变化可能影响到购物车中商品的显示状态,可以在cartStore中:
import { defineStore } from 'pinia';
import { useProductStore } from './productStore';

export const useCartStore = defineStore('cart', {
    state: () => ({
        items: [],
        totalPrice: 0
    }),
    actions: {
        // 原有actions...
    },
    setup() {
        const productStore = useProductStore();
        watch(() => productStore.products, () => {
            // 当商品列表变化时,检查购物车中商品是否还存在于商品列表,不存在则移除
            this.items = this.items.filter(item => productStore.products.some(product => product.id === item.id));
        });
        return {};
    }
});
  1. 事件总线
    • 虽然Pinia本身没有内置事件总线,但可以使用第三方库如mitt来实现模块间事件通信。例如,在productStore中商品价格更新时通知cartStore重新计算总价:
    • 安装mittnpm install mitt
    • main.js中创建事件总线实例:
import mitt from'mitt';
const emitter = mitt();
app.config.globalProperties.$emitter = emitter;
- 在`productStore`中:
import { defineStore } from 'pinia';

export const useProductStore = defineStore('product', {
    state: () => ({
        products: []
    }),
    actions: {
        updateProductPrice(productId, newPrice) {
            const product = this.products.find(p => p.id === productId);
            if (product) {
                product.price = newPrice;
                this.$emitter.emit('productPriceUpdated');
            }
        }
    }
});
- 在`cartStore`中:
import { defineStore } from 'pinia';

export const useCartStore = defineStore('cart', {
    state: () => ({
        items: [],
        totalPrice: 0
    }),
    actions: {
        // 原有actions...
    },
    setup() {
        const cartStore = useCartStore();
        cartStore.$emitter.on('productPriceUpdated', () => {
            cartStore.calculateTotalPrice();
        });
        return {};
    }
});