Vue.js实现内容toggle切换:传递字符串动态访问data变量的方法
问题修复
基础语法错误排查
你现在的代码有两处硬语法错误,不修正的话根本跑不起来:
- 组件的
data配置写法错误
Vue规定组件的data必须是一个返回状态对象的函数,你现在写的代码漏了return,定义的data1/data2/data3根本不会被挂载到组件实例上,就算其他逻辑写对了,访问this.data1的时候也会报undefined。- 错误写法:
data() { data1 : false, data2 : false, data3 : false } - 修正写法:
data() { return { data1: false, data2: false, data3: false } }
- 错误写法:
- 动态属性访问的写法错误
JS里用字符串变量当属性名访问对象时,格式是对象[属性变量],不要在对象和中括号之间加多余的点,你写的this.[curData]完全不符合JS语法规则,浏览器会直接抛出语法错误。- 错误写法:
this.[curData] = !this.[curData]; - 修正写法:
this[curData] = !this[curData];
- 错误写法:
业务逻辑调整
你现在的showData方法开头默认把三个状态全部置为false,再对当前传入的属性做取反,会导致不管点哪个按钮,最终对应的内容块永远是显示状态,没法实现“再点一次同一个按钮就关闭当前块”的toggle效果,根据你的实际需求可以选择对应写法:
- 需求1:任意时刻只显示一个内容块,点击对应按钮就切换到对应块(块之间互斥)
这种模式下不需要做取反操作,直接把当前块的状态设为true即可,逻辑更简单不容易出错:showData(curData) { // 先把所有块的状态重置为关闭 this.data1 = this.data2 = this.data3 = false; // 打开当前点击对应的块 this[curData] = true; } - 需求2:每个内容块独立控制开关,点一次开、再点一次关,块之间不互斥
这种模式下删掉开头重置所有状态的代码就行,每个块自己维护自己的显示状态,互不影响:showData(curData) { // 直接对当前块的状态做取反 this[curData] = !this[curData]; }
扩展性优化
如果后续内容块的数量会不断增加,挨个在data里定义单独的状态变量、挨个写重置代码会非常繁琐,可以把所有开关状态存在一个对象里统一管理:
- 调整
data的结构:data() { return { showMap: { data1: false, data2: false, data3: false } } } - 调整模板里的
v-show绑定,读取对象内的属性:<div @click="showData('data1')">click</div> <div @click="showData('data2')">click</div> <div @click="showData('data3')">click</div> <div v-show="showMap.data1">Show data 1</div> <div v-show="showMap.data2">Show data 2</div> <div v-show="showMap.data3">Show data 3</div> - 调整方法逻辑,遍历对象统一重置状态,后续新增块不需要改重置逻辑:
showData(curData) { // 遍历所有状态,统一设为关闭 Object.keys(this.showMap).forEach(key => { this.showMap[key] = false; }) // 打开当前点击对应的块 this.showMap[curData] = true; }
内容的提问来源于stack exchange,提问作者prettyInPink
相关产品推荐
相关产品推荐

