如何向Inertia.js持久化布局的Header传递products属性?
解决方案:将Products传递给持久化布局的Header组件
根据你的需求,下面提供三种常用实现方式,可根据场景选择:
方法1:页面组件向布局传递Props(单页面场景)
如果仅需要在特定页面(比如产品列表页)将Products传给Header,可通过页面向布局传递自定义Props:
步骤1:在页面组件中设置布局Props
以产品列表页(Products.vue)为例:
<template> <!-- 页面内容 --> </template> <script setup> import { usePage } from '@inertiajs/vue3' // 接收后端传递的products props const props = defineProps({ products: { type: Array, required: true } }) // 将products注入到页面props的layoutProps字段 const pageProps = usePage().props.value pageProps.layoutProps = { products: props.products } </script>
步骤2:在MainLayout中接收并传递给Header
修改MainLayout.vue:
<template> <Header :products="layoutProps.products || []" /> <main> <slot /><!-- 页面内容插槽 --> </main> </template> <script setup> import { usePage } from '@inertiajs/vue3' import Header from './Header.vue' const { props } = usePage() // 获取页面传递的布局props,默认空对象 const layoutProps = props.layoutProps || {} </script>
步骤3:在Header中使用Products实现搜索
<template> <div class="header-search"> <input v-model="searchQuery" placeholder="搜索产品..." /> <ul v-if="filteredProducts.length"> <li v-for="product in filteredProducts" :key="product.id"> {{ product.name }} </li> </ul> </div> </template> <script setup> import { ref, computed } from 'vue' const props = defineProps({ products: { type: Array, default: () => [] } }) const searchQuery = ref('') // 计算属性实现筛选 const filteredProducts = computed(() => { const query = searchQuery.value.toLowerCase() return props.products.filter(product => product.name.toLowerCase().includes(query) ) }) </script>
方法2:全局共享Products(多页面场景)
如果所有页面的Header都需要访问Products,可通过Inertia的全局共享数据功能实现:
步骤1:后端共享Products数据(以Laravel为例)
在后端的Inertia配置中添加共享数据:
// app/Providers/AppServiceProvider.php use Inertia\Inertia; public function boot() { Inertia::share([ 'products' => fn () => \App\Models\Product::select('id', 'name')->get()->toArray(), ]); }
步骤2:在Header组件中直接获取全局数据
<template> <!-- 搜索UI同方法1 --> </template> <script setup> import { usePage } from '@inertiajs/vue3' import { ref, computed } from 'vue' const { props } = usePage() const searchQuery = ref('') const filteredProducts = computed(() => { const query = searchQuery.value.toLowerCase() return props.products.filter(product => product.name.toLowerCase().includes(query) ) }) </script>
方法3:状态管理(复杂场景)
如果Products需要在多个组件中修改、共享,推荐使用Pinia状态管理:
步骤1:创建Pinia Store
// stores/productStore.js import { defineStore } from 'pinia' export const useProductStore = defineStore('products', { state: () => ({ list: [] }), actions: { // 设置产品列表 setProducts(products) { this.list = products } }, getters: { // 带搜索参数的筛选器 filteredProducts: (state) => (query) => { const lowerQuery = query.toLowerCase() return state.list.filter(product => product.name.toLowerCase().includes(lowerQuery) ) } } })
步骤2:在app.js中注册Pinia
修改你的app.js:
... import { createPinia } from 'pinia' import MainLayout from "./Pages/Layouts/MainLayout.vue"; createInertiaApp({ title: (title) => `${title} - ${appName}`, resolve: (name) => { const pages = import.meta.glob("./Pages/**/*.vue", { eager: true }); let page = pages[`./Pages/${name}.vue`]; page.default.layout = name.startsWith("Dashboard/") ? undefined : MainLayout; return page; }, setup({ el, App, props, plugin }) { return createApp({ render: () => h(App, props) }) .use(plugin) .use(createPinia()) // 注册Pinia .mount(el); }, progress: { color: "#4B5563", }, });
步骤3:在页面组件中初始化Store数据
<!-- Products.vue --> <script setup> import { useProductStore } from '@/stores/productStore' const props = defineProps({ products: { type: Array, required: true } }) const productStore = useProductStore() // 将后端传递的products存入Store productStore.setProducts(props.products) </script>
步骤4:在Header组件中使用Store
<template> <!-- 搜索UI同方法1 --> </template> <script setup> import { useProductStore } from '@/stores/productStore' import { ref, computed } from 'vue' const productStore = useProductStore() const searchQuery = ref('') const filteredProducts = computed(() => { return productStore.filteredProducts(searchQuery.value) }) </script>
内容的提问来源于stack exchange,提问作者ahmad kharabsheh
相关产品推荐
相关产品推荐

