Flutter:不使用全局变量实现组件传值并跳转至主屏幕问题
组件传值+跳转主屏幕(无全局变量方案)
1. 路由参数传递(单页应用首选)
如果项目用了React Router、Vue Router这类路由库,直接把数据编码后通过路由query参数传递,同时跳转到主屏幕路由。
React 示例
// 子组件触发跳转逻辑 const handleJumpWithData = () => { const transferData = { cardId: 456, textContent: '用户输入内容' }; // 把对象转成JSON字符串并编码,避免特殊字符问题 const encodedData = encodeURIComponent(JSON.stringify(transferData)); // 跳转到主屏幕路由并带参数 navigate('/main?screenData=' + encodedData); }; // 主屏幕组件接收参数 import { useLocation } from 'react-router-dom'; const MainScreen = () => { const location = useLocation(); const searchParams = new URLSearchParams(location.search); const encodedData = searchParams.get('screenData'); const receivedData = encodedData ? JSON.parse(decodeURIComponent(encodedData)) : null; return ( <div className="main-screen"> {receivedData && <CardComponent data={receivedData} />} </div> ); };
Vue 示例
<!-- 子组件中触发跳转 --> <script setup> import { useRouter } from 'vue-router'; const router = useRouter(); const sendDataAndJump = () => { const transferData = { cardId: 456, textContent: '用户输入内容' }; router.push({ path: '/main', query: { screenData: encodeURIComponent(JSON.stringify(transferData)) } }); }; </script> <!-- 主屏幕组件接收参数 --> <script setup> import { useRoute } from 'vue-router'; const route = useRoute(); const receivedData = route.query.screenData ? JSON.parse(decodeURIComponent(route.query.screenData)) : null; </script>
2. 组件层级回调(适用于有父子/祖孙关系的组件)
如果触发传值的组件和主屏幕同属一个父组件管辖,直接用回调函数传递数据,同时切换主屏幕的显示状态。
React 示例
// 父组件(管理子组件和主屏幕的切换) const AppContainer = () => { const [showMain, setShowMain] = useState(false); const [componentData, setComponentData] = useState(null); // 接收子组件传递的数据并切换到主屏幕 const receiveData = (data) => { setComponentData(data); setShowMain(true); }; return ( <div> {!showMain ? <InputCard onPassData={receiveData} /> : <MainScreen data={componentData} />} </div> ); }; // 子组件(比如文本框卡片) const InputCard = ({ onPassData }) => { const [inputValue, setInputValue] = useState(''); const handleSubmit = () => { onPassData({ content: inputValue }); }; return ( <div className="input-card"> <input value={inputValue} onChange={(e) => setInputValue(e.target.value)} /> <button onClick={handleSubmit}>确认并返回主屏幕</button> </div> ); };
Vue 示例
<!-- 父组件 --> <template> <div> <InputCard v-if="!showMain" @pass-data="receiveData" /> <MainScreen v-else :data="componentData" /> </div> </template> <script setup> import { ref } from 'vue'; import InputCard from './InputCard.vue'; import MainScreen from './MainScreen.vue'; const showMain = ref(false); const componentData = ref(null); const receiveData = (data) => { componentData.value = data; showMain.value = true; }; </script> <!-- 子组件 --> <template> <div class="input-card"> <input v-model="inputValue" /> <button @click="sendData">确认并返回主屏幕</button> </div> </template> <script setup> import { ref } from 'vue'; const emit = defineEmits(['pass-data']); const inputValue = ref(''); const sendData = () => { emit('pass-data', { content: inputValue.value }); }; </script>
3. 临时存储(会话/本地存储,无层级关联时用)
如果组件之间没有直接层级关系,也不想用路由参数,可以用sessionStorage临时存数据,跳转后主屏幕读取,用完及时删除避免残留。
// 子组件中存储数据并跳转 const handleJumpAndStore = () => { const transferData = { id: 789, content: '临时传递内容' }; sessionStorage.setItem('tempScreenData', JSON.stringify(transferData)); // 用路由跳转或直接跳转 window.location.href = '/main'; }; // 主屏幕组件读取并清理数据 const MainScreen = () => { useEffect(() => { const storedData = sessionStorage.getItem('tempScreenData'); if (storedData) { const receivedData = JSON.parse(storedData); // 在这里使用数据渲染组件 console.log(receivedData); // 用完删除,防止下次进入主屏幕读到旧数据 sessionStorage.removeItem('tempScreenData'); } }, []); return <div className="main-screen">...</div>; };
内容的提问来源于stack exchange,提问作者Sami Ullah
相关产品推荐
相关产品推荐

