vue中用v-for的item属性作为v-if组件渲染条件时不起作用
上篇讲到了使用组件递归实现树形菜单,现在要来实现点击切换菜单项的展开收起状态。
我的想法时,在处理菜单列表数据时,给每个有子菜单的菜单项添加一个showChild属性,然后在Menu组件渲染时,通过v-if绑定item.showChild来控制子菜单项的显示与隐藏:
<ul class="menu"> <li class="menu-item" v-for="item in list" ::key="item.name"> <div class="menu-item-content" @click="toggleShow(item)"> <span v-if="item.children && item.children.length">📂</span> <span class="menu-item-name">{{item.name}} </span> </div> <Menu v-if="item.showChild && item.children && item.children.length" :list="item.children"></Menu> </li> </ul>
点击切换展开和收起状态:
methods: { toggleShow(item) { if (item.children && item.children.length) { item.showChild = !item.showChild; } } }
然后我发现点击根本不起作用,试着打印了一下点击的item的showChild,发现是改变了的,但是没有在页面是实时渲染新的值。
后来我在网上搜索了相关资料,终于找到了原因:
因为数据层次太多,render函数没有自动更新,需手动强制刷新。
这里说的强制渲染,就是通过调用this.$forceUpdate()来手动强制渲染已改变的页面数据并刷新页面,所以在toggleShow方法后面添加这一行代码就可以了:
methods: { toggleShow(item) { if (item.children && item.children.length) { item.showChild = !item.showChild; this.$forceUpdate(); } } }