Vue中v-if调用方法对比continentId与用户scope判断不生效
问题原因
过滤判断不生效是4个核心代码错误导致的:
- 模板里
v-if="country.continentId==setup"访问的setup是你定义在methods里的方法本身,不是接口返回的用户scope值。Options API规范下,methods里return的变量不会自动挂载到组件实例,模板根本读不到你在setup方法内部定义的scope变量。 - mounted钩子中调用
this.setup()时没有加await,请求用户scope的异步操作还没返回结果,就已经执行完国家列表拉取逻辑,就算后续拿到scope值也没有触发对应匹配。 - setup方法内部写法错误:一是在Options API环境下直接用组合式API的
ref没有实际作用,二是response.json()本身是Promise对象,你没加await就直接取content.scope,拿到的不是实际接口返回数据,三是把token硬编码为"??",实际鉴权场景下无法拿到正确的用户权限数据。 - 存在隐式类型转换坑:如果接口返回的scope是字符串类型,而国家数据里的
continentId是数字类型,松散相等在部分场景下会出现匹配异常。
修复方案
- 在组件的
data里定义响应式变量存储用户scope,避免方法内局部变量无法被模板访问 - 把获取用户scope的方法重命名,避免和Vue3内置的组合式API入口
setup重名,修正异步请求写法,拿到结果后直接赋值给data里的变量 - mounted钩子中按顺序执行异步逻辑:先等用户scope拉取完成,再拉取国家列表数据
- 模板中把判断条件的对比值改成data里存储的用户scope变量,统一对比值的类型
修复后完整代码
脚本逻辑部分
export default { data() { return { countries: [], showGrid: true, searchbar: true, userScope: null, // 存储当前登录用户的scope值 } }, methods: { async getCountries() { const countryQuery = this.$route.query.query const baseUrl = "https://localhost:44391/api/Pho/GetCountries" if (!countryQuery) { const res = await axios.get(baseUrl) this.countries = res.data } else { const res = await axios.get(`${baseUrl}?country=${countryQuery}`) this.countries = res.data this.searchbar = false } }, async getUserScope() { // 替换成你实际从本地存储/cookie中读取的真实token,不要硬编码占位值 const token = localStorage.getItem("authToken") || "" const response = await fetch( "https://localhost:44391/api/Auth/UserScope", { headers: { "Content-Type": "application/json", Authorization: `Bearer ${token}`, }, credentials: "include", } ) const content = await response.json() // 加await等待json解析完成 // 统一转为数字类型,和continentId类型对齐避免匹配异常 this.userScope = Number(content.scope) }, }, async mounted() { // 先等待用户权限拉取完成,再拉取国家列表 await this.getUserScope() await this.getCountries() }, }
模板部分
<div class="container w-75" v-show="showGrid"> <div class="row" style="width:900px; height:900px; padding-left:200px"> <!-- v-for不要绑定整个country对象作为key,绑定唯一标识countryId性能更好,也能避免渲染异常 --> <div class="col-md-4" v-for="country of countries" v-bind:key="country.countryId"> <div v-if="country.continentId === userScope" class="card p-3" style="cursor:pointer"> <router-link :to="{ path: '/FetchData', query: { query: country.countryName}}"> <div class="d-flex flex-row mb-3"> <div class="d-flex flex-column ml-2"><span>{{country.countryId}}</span></div> </div> <h6 style="text-align:left">{{country.countryName}}</h6> </router-link> </div> </div> </div> </div>
内容的提问来源于stack exchange,提问作者Nesrine Missaoui
相关产品推荐
相关产品推荐

