赞
踩
问题不太好描述,复现一下场景:
列表页面,通过新增按钮打开弹窗
弹窗中还有列表,通过弹窗中的新增按钮操作列表
列表中有插槽,其中一项点击可以打开新的弹窗
新的弹窗用来勾选数据回显到列表中,处理为当前项的子节点
点确定之后,列表被处理成类似这种效果
通过确定按钮,将勾选的list数组传到父组件,进行赋值操作
然后log打印父组件列表的数据,发现打印有值,但是页面上什么都不展示
解决这种问题,常用的方法有
this.$ set / 扩展运算符 / this.$nextTick /setTimeout
我都试过了,依然不起作用
解决办法是父组件的列表每次新增的时候得有children字段
代码如下:
父组件的新增
addList() {
this.dataSource.push({
id: uuid(),
hasItem: false,
children:[],//必须有
})
},
父组件列表,用的是element文档上树形数据与懒加载示例的第一个
<el-table
row-key="id"
default-expand-all
:data="dataSource"
:tree-props="{ children: 'children' }"
border
ref="table"
highlight-current-row
:height="screenHeight - 500 + 'px'"
class="elTable mgrTable"
style="width: 100%; margin-bottom: 20px"
>
勾选数据后的确定事件
checkTreesure(arr) { //处理索引,可忽略 let childrenSum = this.dataSource.reduce((sum, item) => { return sum + (item.children ? item.children.length : 0) }, 0) let newIdx = this.checkTreeIndex - childrenSum if (!this.dataSource[newIdx]) { this.dataSource.splice(newIdx, 1, {}) } if (!this.dataSource[newIdx].children) { this.dataSource[newIdx].children = [] } //重点,使用this.$set或者直接赋值也可以 this.$set(this.dataSource[newIdx], 'children', arr.map(item => { return { id: uuid(), sizes: item.dictValue, hasItem: true, pid: this.dataSource[newIdx].id, }; })); //替换写法,直接赋值 // const newArr = arr.map(item => { // return { // id: uuid(), // sizes: item.dictValue, // hasItem: true, // pid: this.dataSource[newIdx].id, // }; // }) // this.dataSource[newIdx].children = newArr this.$nextTick(() => { this.$refs.table.doLayout(); }); this.checkTreeVisible = false },
总结:
这个bug应该不是组件嵌套过深的原因,而是新增的时候没有加children,组件的渲染依赖于特定的数据结构或状态,利用索引直接设置一个项,Vue 可能无法追踪它的变化
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。