Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

vuejs conditional wrapper

In my nativescript-vue application I have a singleFile component called profileForm. I want to use that component in two ways, if the user is logged in I want to have that component as the slot of my layout component to edit profile. Otherwise I want is as a registration form.

I don't want to create an extra component for handling this. So in one case I would like to have my component wrapped in a tag so I can navigate to it, with Vue.$navigateTo, in another case I'd like to wrap it in a component. But the component has a tag in itself so in that case I don't want the anymore.

In django templates I would do something like this:

<template>
  <Page v-if="is_signup" actionBarHidden="true">
  <AppLayout v-else title="Profile">
  ...
  </AppLayout v-else>
  </Page v-if="is_signup">
</template>

But of course this would not work in vuejs. Is there any way to achieve this in vuejs?

I could create a new component and wrap this there like so:

<template>
  <Page v-if="is_signup" actionBarHidden="true">
    <ProfileForm/>
  </Page>
  <AppLayout v-else title="Profile">
    <ProfileForm/>
  </AppLayout>
</template>

But I'd rather not create a new component for this task.

I was hoping to get something like this:

<template>
  <template :is="is_signup?'Page':'AppLayout'" :v-bind="is_signup?{actionBarHidden:true}:{title:'Profile'}">
    ...
  </template>
</template>

Does nativescript-vue have such syntax?

like image 894
yukashima huksay Avatar asked Sep 14 '19 14:09

yukashima huksay


Video Answer


2 Answers

This can be solved by using a generic component element:

<template>
    <component :is="is_signup ? 'Page' : 'AppLayout'" actionBarHidden="true">
    ...
   </component>
</template>

See https://v2.vuejs.org/v2/guide/components.html#Dynamic-Components
Note that passing a prop not declared in the component (for instance, actionBarHidden being passed to AppLayout, which does not use it) has no effect and is completely safe.

This is an old question but I found myself in the same situation, so I came back to add this answer. Edit: @MarcRo already provided the same answer, somewhat hidden in a comment above.

like image 123
pecus Avatar answered Sep 29 '22 22:09

pecus


One way to do it:

I would go with a v-if / v-else logic if you have only two distinct but predefined options. Simply more semantic.

<template>
  <Page
    v-if="is_signup"
    :actionBarHidden="true"
  >
    <Label :text="'hello'" />
  </Page>
  <Label
    v-else
    :text="'hello'"
  />
</template>

<script>
import Label from '../components/Label.vue';
import Page from '../components/Page.vue';

export default {
  components: {
    Page,
    Label,
  },

  data() {
    return {
      is_signup: false, // you will have to find a way to set is_signup correctly
    };
  },
}
</script>

There are several other ways to achieve the same result; however without knowing more about the requirements I will just leave you with this first option :)

like image 21
MarcRo Avatar answered Sep 29 '22 21:09

MarcRo