Answer a question

I'm building an app with Vue 3 and TS 4.4 and bundled with Vite 2. I've got a LoginPage.vue file with these contents:

<script lang="ts" setup>
const props = defineProps<{
  message?: string;
  redirectOnSubmit?: boolean;
  showRegisterLink?: boolean;
}>();

console.log({ ...props });
</script>

<template>
  ... login form and whatnot
</template>

This component is being passed to vue-router

export const router = createRouter({
  history: createWebHistory(),
  routes: [
    { name: RouteName.LOGIN, path: "/login", component: LoginPage },
    { name: RouteName.REGISTER, path: "/register", component: RegisterPage },
  ],
});

The problem I'm having is when the login page setup script gets run, it logs this:

{ redirectOnSubmit: false, showRegisterLink: false, message: undefined }

Why are my optional boolean props being forced to false instead of undefined? Is there any way to turn this off? If I switch message to message?: boolean, it also gets switched to false.

I'd like to default these props to true if nothing is passed, but as-is there's no way for me to distinguish between passing false and omitting the props entirely.

Answers

Vue defaults Boolean props to false if no default was specified in the prop declaration. The author of Vue explains the reasoning:

The boolean casting follows the same rule of a boolean attribute: presence of any value are casted to true, absence means false.

To default the props to true, declare the prop with a default option of true, using the object-based syntax for the prop declaration, as seen in this Options API example:

<script>
export default {
  props: {
    myOptionalBool: {
      type: Boolean,
      default: true, 👈
    }
  }
}
</script>

Option 1: defineProps(props)

In <script setup>, defineProps() accepts the prop declaration object (shown above) as a function argument. Since defineProps() only accepts either the function argument or the generic type argument, all props would have to be declared in the function argument:

<script lang="ts" setup>
const props = defineProps({
  message: String,
  showRegisterLink: {
    type: Boolean,
    default: true,
  },
  redirectOnSubmit: {
    type: Boolean,
    default: true,
  },
})
</script>

demo 1

Option 2: withDefaults() and defineProps<T>()

The withDefaults() macro can be used with defineProps<T>() to specify default values for specific props:

<script lang="ts" setup>
interface Props {
  message?: string
  redirectOnSubmit?: boolean
  showRegisterLink?: boolean
}
const props = withDefaults(defineProps<Props>(), {
  redirectOnSubmit: true,
  showRegisterLink: true,
})
</script>

demo 2

Logo

前往低代码交流专区

更多推荐