如何在Vue中实现类似React useState的功能?并排查搜索栏切换功能的代码问题
如何在Vue中实现类似React useState的功能?并排查搜索栏切换功能的代码问题
嘿,我来帮你排查这个搜索栏切换的问题,顺便讲讲Vue里怎么实现类似React useState的响应式状态管理~
首先,你的代码核心问题出在修改响应式变量的方式不对。在Vue里,用ref创建的响应式变量,本质是一个包裹着实际值的Ref对象,和React的useState逻辑类似,但修改的时候得通过.value属性来操作,直接给变量赋值会把它从响应式的Ref对象变成普通的布尔值,这样UI就不会跟着状态更新了。
咱们看你写的toggleSearchBar函数:
const toggleSearchBar = () => { if (searchBarOpen) { searchBarOpen = false; // 这里直接覆盖了Ref对象,彻底失去响应性 } else { searchBarOpen = true; } console.log({ searchBarOpen }); };
这里你直接把searchBarOpen赋值成true/false,相当于把原来的响应式Ref对象给替换成了普通变量,Vue没法再追踪它的变化,所以点击按钮后UI完全没反应。
另外还有两个小细节问题:
- 你的
<template>标签没闭合,最后一行应该是</template>,少了个反斜杠 - 关闭按钮里没有文字,用户根本不知道点它是干嘛的,建议加个“Close Search bar”
下面是修正后的完整代码:
修正后的模板部分
<template> <button @click="toggleSearchBar" v-if="!searchBarOpen" > Open Search bar </button> <div v-else > <input placeholder="Search..." /> <button @click="toggleSearchBar" > Close Search bar </button> </div> </template>
修正后的脚本部分
<script setup> import { ref } from "vue"; // 用const更规范,因为我们不会重新给变量本身赋值,只修改它的.value const searchBarOpen = ref(false); const toggleSearchBar = () => { // 其实可以简化成一行:searchBarOpen.value = !searchBarOpen.value if (searchBarOpen.value) { searchBarOpen.value = false; } else { searchBarOpen.value = true; } // 要看到实际值可以改成console.log(searchBarOpen.value) console.log({ searchBarOpen }); }; </script>
最后再总结下Vue里类似React useState的用法:
ref就对应React的useState,用来创建基础类型的响应式状态(比如布尔、字符串、数字)- 声明时用
const xxx = ref(初始值),因为我们不需要重新给变量本身赋值,只需要修改它的.value - 在模板里使用的时候,不需要加
.value,Vue会自动帮我们解包 - 如果是复杂对象,可以用
reactive,和React里用useState存对象类似,但修改时直接操作属性就行,不用.value
备注:内容来源于stack exchange,提问作者youssefrag
相关产品推荐
相关产品推荐

