美文网首页
vue中原始数据未分类的情况下怎样区分父元素有无目标子元素并添加

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

作者: 落崖惊风yxy | 来源:发表于2018-01-26 11:47 被阅读0次

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

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

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

<ul v-for="(item,index) in failing.testcase" :class="!item.time?'especial':''"  @click="showdevDetail(item)" >
    <li class="time" v-if="item.time">{{item.time+"s"}}</li>
    <li>{{item.name}}</li>
     <li v-if="item.devDetail" class="especial" :class="{'showdev':item.show}">
             <ul class="devdetail" v-for="item in item.devDetail" v-show="devdetailShow">
                   <li>{{item.name}}</li>
                   <li>{{item.failure}}</li>
             </ul>
      </li>
</ul>

开始的时候,我给了一个全局开关: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:

<li v-if="item.devDetail" class="especial" :class="{'showdev':item.show}">
                            <ul class="devdetail" v-for="item in item.devDetail" v-show="devdetailShow">
                                <li>{{item.name}}</li>
                                <li>{{item.failure}}</li>
                                <li v-if="item.tapdID">{{item.tapdID}}</li>
                            </ul>
                        </li>

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

<li v-if="item.devDetail" class="especial" :class="{'showdev':item.show}">
       <div v-show="item.devdetailShow">
                <ul class="devdetail" v-for="item in item.devDetail">
                        <li>{{item.name}}</li>
                        <li>{{item.failure}}</li>
                        <li v-if="item.tapdID">{{item.tapdID}}</li>
                  </ul>
         </div>
 </li>

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中原始数据未分类的情况下怎样区分父元素有无目标子元素并添加

    最近写了一个页面,需求如下: 部分父元素有特殊的子元素,部分父元素没有特殊的子元素;特殊子元素开始的时候是隐藏的,...

  • vue 高阶组件必备知识$attrs,inheritAttrs,

    1,inheritAttrs介绍 vue默认情况下,父组件是可以直接给子组件的根元素添加class和style的,...

  • CSS小tip整理

    1.利用css在列表靠头和末尾添加箭头: 2.让父元素包含浮动的子元素: 添加一个进行清理的元素 让父元素浮动,并...

  • 清除浮动

    存在父元素 方法一:父元素添加 overflow:hidden方法二:父元素同子元素一起添加 float:left...

  • 13、添加元素的几种方式

    添加元素的几种方式: (1)append() 父元素.append(子元素),把子元素添加到父元素的末尾 新创建标...

  • css基础布局(续)

    左右布局 float通过在每个子元素添加float,并在父元素中添加clearfix,可以实现子元素的浮动,其意为...

  • 解决浮动元素父级塌陷的问题

    如果网页中某个元素内具有多个带有浮动属性的子元素,使得父元素发生塌陷,则给父元素添加高度不能解决父元素塌陷问题。 ...

  • 弹性盒模型

    弹性盒模型 由父元素控制子元素布局的方案,需要给父元素添加flex样式,任意元素都可添加flex样式 displa...

  • CSS - 兼容性

    定位 在 IE6、IE7中,若子元素需相对于父元素进行定位,则需为父元素指定高度,或者为父元素添加以下样式: * ...

  • css清除浮动影响

    初始代码环境如下: 方法1:(并算不上清除浮动)在父元素中计算并设定子元素所占高度即 方法2:利用添加子元素cle...

网友评论

      本文标题:vue中原始数据未分类的情况下怎样区分父元素有无目标子元素并添加

      本文链接:https://www.haomeiwen.com/subject/jabiaxtx.html