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

后端 未结 3 1072
[愿得一人]
[愿得一人] 2021-02-20 14:15

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

相关标签:
3条回答
  • 2021-02-20 14:38

    Hiding a div hides all contained (child) divs. Move the parent out into a container div, do not nest the child div in it.

    0 讨论(0)
  • 2021-02-20 14:38

    I made the following component. It doesn't seem perfect as it requires to also define parent of the potential wrapper element and both types and properties are passed as 'props' instead of using pure HTML, but it should work.

    <template>
      <div :is="mainElementType"
        v-bind="mainElementProperties">
        <div v-if="wrapperElementType"
          :is="wrapperElementType"
          v-bind="wrapperElementProperties"
          class="wrapper-element">
          <slot/>
        </div>
        <slot v-else/>
      </div>
    </template>
    
    <script>
      export default {
        props: {
          mainElementType: {
            default: 'div'
          },
          mainElementProperties: Object,
          wrapperElementType: String,
          wrapperElementProperties: String
        }
      }
    </script>
    

    Usage example below.

    <optional-wrapper main-element-type="h2"
      :wrapper-element-type="displayWrapperElement && 'span'">
      <span class="wrapped">WRAPPED</span>
    </optional-wrapper>
    
    0 讨论(0)
  • 2021-02-20 14:44

    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>
    

    0 讨论(0)
提交回复
热议问题