You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular 13中非父子组件间搜索结果共享实现方法咨询

非父子组件间搜索结果传递的实现方案

下面是几种实用的实现方式,覆盖不同复杂度的场景:

方案1:全局状态管理(推荐用于复杂场景)

不管是React还是Vue,全局状态管理都是最稳妥的选择,能轻松跨组件共享状态。

React + Redux Toolkit 示例

  • 第一步:创建搜索状态切片
// features/search/searchSlice.js
import { createSlice } from '@reduxjs/toolkit';

const initialState = { results: [] };

const searchSlice = createSlice({
  name: 'search',
  initialState,
  reducers: {
    setSearchResults: (state, action) => {
      state.results = action.payload;
    }
  }
});

export const { setSearchResults } = searchSlice.actions;
export default searchSlice.reducer;
  • 第二步:Home组件中更新全局状态
// Home.jsx
import { useDispatch } from 'react-redux';
import { setSearchResults } from './features/search/searchSlice';

function Home() {
  const dispatch = useDispatch();

  const handleSearch = (searchQuery) => {
    // 这里替换成实际的搜索请求逻辑
    const results = mockFetchSearchResults(searchQuery);
    dispatch(setSearchResults(results));
  };

  return (
    <div>
      <input 
        type="text" 
        placeholder="输入关键词搜索"
        onChange={(e) => handleSearch(e.target.value)} 
      />
    </div>
  );
}
  • 第三步:表格组件中读取状态并渲染
// ResultsTable.jsx
import { useSelector } from 'react-redux';

function ResultsTable() {
  const searchResults = useSelector(state => state.search.results);

  return (
    <table border="1">
      <thead>
        <tr>
          <th>ID</th>
          <th>内容</th>
        </tr>
      </thead>
      <tbody>
        {searchResults.map(item => (
          <tr key={item.id}>
            <td>{item.id}</td>
            <td>{item.content}</td>
          </tr>
        ))}
      </tbody>
    </table>
  );
}

Vue 3 + Pinia 示例

  • 第一步:创建搜索状态仓库
// stores/search.js
import { defineStore } from 'pinia';

export const useSearchStore = defineStore('search', {
  state: () => ({ results: [] }),
  actions: {
    setResults(data) {
      this.results = data;
    }
  }
});
  • 第二步:Home组件中更新仓库状态
<!-- Home.vue -->
<script setup>
import { useSearchStore } from '@/stores/search';

const searchStore = useSearchStore();

const handleSearch = (query) => {
  const results = mockFetchSearchResults(query);
  searchStore.setResults(results);
};
</script>

<template>
  <input 
    type="text" 
    placeholder="输入关键词搜索"
    @input="handleSearch($event.target.value)" 
  />
</template>
  • 第三步:表格组件中读取状态
<!-- ResultsTable.vue -->
<script setup>
import { useSearchStore } from '@/stores/search';

const searchStore = useSearchStore();
</script>

<template>
  <table border="1">
    <thead>
      <tr>
        <th>ID</th>
        <th>内容</th>
      </tr>
    </thead>
    <tbody>
      <tr v-for="item in searchStore.results" :key="item.id">
        <td>{{ item.id }}</td>
        <td>{{ item.content }}</td>
      </tr>
    </tbody>
  </table>
</template>

方案2:Context API(React轻量场景首选)

如果不想引入重型状态管理库,React的Context API足够应对简单的跨组件状态共享:

  • 第一步:创建搜索上下文
// SearchContext.js
import { createContext, useContext, useState } from 'react';

const SearchContext = createContext();

export function SearchProvider({ children }) {
  const [results, setResults] = useState([]);
  return (
    <SearchContext.Provider value={{ results, setResults }}>
      {children}
    </SearchContext.Provider>
  );
}

export function useSearch() {
  return useContext(SearchContext);
}
  • 第二步:在根组件包裹SearchProvider,确保两个组件都在其范围内
  • 第三步:Home组件中更新状态
// Home.jsx
import { useSearch } from './SearchContext';

function Home() {
  const { setResults } = useSearch();

  const handleSearch = (query) => {
    const results = mockFetchSearchResults(query);
    setResults(results);
  };

  return <input type="text" onChange={(e) => handleSearch(e.target.value)} />;
}
  • 第四步:表格组件中读取状态
// ResultsTable.jsx
import { useSearch } from './SearchContext';

function ResultsTable() {
  const { results } = useSearch();
  // 渲染表格逻辑同前
}

方案3:自定义事件(通用轻量方案)

利用浏览器原生的CustomEvent实现无依赖的跨组件通信:

  • Home组件触发事件:
// Home.js
const handleSearch = (query) => {
  const results = mockFetchSearchResults(query);
  window.dispatchEvent(new CustomEvent('searchResultsUpdated', {
    detail: results
  }));
};
  • 表格组件监听事件:
// ResultsTable.js
import { useEffect, useState } from 'react';

function ResultsTable() {
  const [results, setResults] = useState([]);

  useEffect(() => {
    const handleUpdate = (e) => setResults(e.detail);
    window.addEventListener('searchResultsUpdated', handleUpdate);
    // 组件卸载时清理监听
    return () => window.removeEventListener('searchResultsUpdated', handleUpdate);
  }, []);

  // 渲染表格逻辑同前
}

方案4:URL参数传递(适合需保留搜索状态的场景)

把搜索参数拼到URL上,表格组件通过读取URL参数获取搜索条件并请求结果:

  • Home组件更新URL:
// Home.js
const handleSearch = (query) => {
  const url = new URL(window.location);
  url.searchParams.set('search', query);
  window.history.pushState({}, '', url);
};
  • 表格组件监听URL变化并获取结果:
// ResultsTable.js
import { useEffect, useState } from 'react';

function ResultsTable() {
  const [results, setResults] = useState([]);

  useEffect(() => {
    const fetchResults = async () => {
      const searchQuery = new URLSearchParams(window.location.search).get('search');
      if (searchQuery) {
        const data = await mockFetchSearchResults(searchQuery);
        setResults(data);
      }
    };

    fetchResults();
    // 监听浏览器前进后退事件
    window.addEventListener('popstate', fetchResults);
    return () => window.removeEventListener('popstate', fetchResults);
  }, []);

  // 渲染表格逻辑同前
}

内容的提问来源于stack exchange,提问作者Fares Belaid

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 22:43:14