Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

v-if on a DIV but always display its contents with Vue.js?

Tags:

vue.js

With Vue.js I need to toggle a parent-div, but always show the child-div.

<div v-if="showparent" class="parent">
  <div class="child"> 
    Child should always be visible
  </div>
</div>

As far as I know this is not possible with Vue.js. The v-if directive removes all div's inside when showparent is false.

Any ideas how to achieve this?

like image 248
Dylan Avatar asked Aug 15 '16 16:08

Dylan


People also ask

Can you use V-for in a div?

If you need a single div with class row and all the child component inside that, you should move the v-for to the component instead of the div. React also behaves in same way. To which component you apply the loop, it will repeat in DOM.

What does V-if do in Vue?

The directive v-if is used to conditionally render a block. The block will only be rendered if the directive's expression returns a truthy value.

Can you use V-for and V-if together?

Using v-if and v-for together is not recommended.

Should I use V show or V-if?

As a general rule for performance, v-if has higher toggle costs (whenever the conditional changes) and v-show has higher initial render costs. So if you need to toggle something frequently, use v-show. If the conditional does not change that frequently during the runtime, use v-if.


1 Answers

I have found two ways to do what you want to achieve, first one is to just repeat the child code in a v-else (not optimal because you need to repeat the code..) :

<div v-if="showparent" class="parent">
  <div class="child"> 
    Child should always be visible
  </div>
</div>
<div v-else class="child">
    Child should always be visible
</div>

Or you can create a custom component:


export default {
    name: "v-if-parent",
    props: {
        condition: {
            type: Boolean,
            required: true
        },
        fallbackWrap: {
            type: String,
            default: 'div'
        }
    },
    render(el) {
        if (this.condition) {
            let parent = this.$scopedSlots.parent()[0];
            if (typeof this.$scopedSlots.default === 'function')
                parent.children = this.$scopedSlots.default();
            return parent;
        } else if (typeof this.$scopedSlots.default === 'function') {
            let children = this.$scopedSlots.default();
            if (children.length > 1) {
                //We can only return a single vnode so if multiple children, wrap them in a div
                return el(this.fallbackWrap, null, children)
            }
            return children[0];
        }
        return null;
    }
}

And then use it like this

<v-if-parent :condition="showparent" fallback-wrap="span">
  <template #parent><a href="somelink" /></template>
  This text is always visible <span>You can include absolutely whatever you want in the default slot</span>
</v-if-parent>

Try the Vue Template

like image 181
Tofandel Avatar answered Oct 12 '22 19:10

Tofandel