vue中原始数据未分类的情况下怎样区分父元素有无目标子元素并添加相应的交互

最近写了一个页面,需求如下:

部分父元素有特殊的子元素,部分父元素没有特殊的子元素;特殊子元素开始的时候是隐藏的,点击其父元素展开,再点击就隐藏。相应的,所有数据都在一个json数组里,有没有特殊子元素数据并没有对其进行区分。

我的做法是给所有的父元素都绑定事件,然后判断该父元素有没有特殊子元素,如果有就执行对应事件,如果没有一个return就跳出了。对应的,特殊子元素的显示与隐藏可以给其绑定一个类的开关,如:class="{'showdev':item.show}",如果item.show的值为true就添加上这个类,否则就没有这个类。
html部分如下(最终的html,开始的时候现在看到的item.show是devdetailShow,它所在的li里面的ul则没有使用v-show指令):

  • {{item.time+"s"}}
  • {{item.name}}
    • {{item.name}}
    • {{item.failure}}

开始的时候,我给了一个全局开关:devdetailShow:false

对应的点击事件代码:

showdevDetail:function(item){
        //判断是否存在特殊子元素对应的数据,如果有,则执行对应的隐藏与展开的交互;否则不执行
    if(item.devDetail){
        this.devdetailShow=!this.devdetailShow;
         }else{
        return;
    }
}

函数中的item在绑定事件时传入的是父元素的数据名称,item.devDetail则是特殊子元素的数据名称。
但是实际效果却是无论是哪个元素(有特殊子元素的父元素)触发事件,都会导致所有有特殊子元素的父元素及其子元素都受到影响,然而输出的item又的确是唯一的触发事件的元素的item。这是为什么呢?
原因在于虽然item是针对e.target的,但是开关devdetailShow是针对所有特殊子元素的。无论e.target是哪一个,都会改变全局开关devdetailShow。

既然如此,这个开关就得是针对唯一的e.target的。因为原始数据中并没有相应的可用的开关,所以需要自己添加。
对应的代码如下:

showdevDetail:function(item){
    var me=this;
    if(item.devDetail){
        if(typeof item.show=="undefined"){
            me.$set(item,"show",true)
        }else{
            item.show=!item.show;
        }   
    }else{
        return;
    }
}

因为原始数据里并没有show字段,第一次点击显示也就是show的值为true,第二次点击隐藏也就是show的值为false,点三次点击show的值为true......如此循环。如果没有点击过,那么item.show就不存在,否则不是true就是false。因此并不知道是第几次点击的,所以要先判断item.show是否存在,也就是判断typeof item.show=="undefined"为true还是false。
那么看一下效果,未点击之前,特殊子元素显示了;第一次点击显示,第二次点击隐藏,第三次点击显示.....
不符合需求对不对?需求是未点击之前是隐藏的。查看了一下html部分的代码,产生的一个想法,那就是控制特殊子元素(especial)的子元素(child)的显示与隐藏。一开始就把child隐藏掉,第一次点击后让其显示,然后不管它了。从此以后,especial显示它就显示,especial隐藏它就看不到了,给它的开关是不是全局的都无所谓了。在此我又用上了一开始设置的那个开关devdetailShow,只不过给其换了位置。
对应的代码如下:

showdevDetail:function(item){
    var me=this;
    if(item.devDetail){
        if(typeof item.show=="undefined"){
            me.$set(item,"show",true)
                        //给child设置开关
            me.devdetailShow=!me.devdetailShow;
        }else{
            item.show=!item.show;
        }   
    }else{
        return;
    }
}

可是,发现了吗?目前有两个especial,点击其中一个especial的父元素受到影响的却是另一个especial。第二次点击该especial的父元素,它才产生相应的交互。一旦收起especial,就再也点不开了。这是什么鬼?!!!
看看上边的代码就会发现,开始的时候devdetailShow的值为false,如果是第一次点击devdetailShow就设置为me.devdetailShow=!me.devdetailShow也就是true;那第二次第三次...点击它始终都是false,不显示了呀。
所以,还是需要改动滴,如下:

showdevDetail:function(item){
    var me=this;
        if(item.devDetail){
        if(typeof item.show=="undefined"){
          me.$set(item,"show",true)
          me.devdetailShow=true;
        }else{
        item.show=!item.show;
        me.devdetailShow=true;
        }   
    }else{
    return;
    }
}

现在的效果是,点击其中一个especial的父元素受到影响的却是另一个especial。第二次点击该especial的父元素,它才产生相应的交互。以后每次点击有都是正常的。
没啥说的,再改!显然,全局的快关devdetailShow不行。那就针对性的来吧。类似于设置开关show。
看下下面段html:

    • {{item.name}}
    • {{item.failure}}
    • {{item.tapdID}}
  • 因为函数的参数是外层的item,而不是内层的item in item.devDetail的item,所以为避免冲突,给ul添加一个包裹层,相应的v-show="devdetailShow"也要换位置并进行改动了。如下:
    html代码:

    • {{item.name}}
    • {{item.failure}}
    • {{item.tapdID}}
  • js代码:

    showdevDetail:function(item){
        var me=this;
        if(typeof item.devdetailShow=="undefined"){
            me.$set(item,"devdetailShow",true)
        }else{
            // item.devdetailShow=!item.devdetailShow;
            item.devdetailShow=true;
        }
        if(item.devDetail){
                if(typeof item.show=="undefined"){
                    me.$set(item,"show",true)
            }else{
                    item.show=!item.show;
            }   
        }else{
            return;
        }
    }
    

    问题终于得以解决。但是还有一点瑕疵哦!就是第一次点击父元素时要双击才能显示对应的especial,以后的每次点击单击就ok了。

    你可能感兴趣的:(vue中原始数据未分类的情况下怎样区分父元素有无目标子元素并添加相应的交互)