Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Set the def attribute, the props received by the component are still the default type #284

Closed
bosens-China opened this issue Jul 29, 2022 · 12 comments
Assignees

Comments

@bosens-China
Copy link

export const switchProps = () => {
  return {
    modelValue: bool().def(undefined),
    disabled: bool(),
  };
};
import { defineComponent, ref } from 'vue';
import { switchProps } from './switchTypes';

export default defineComponent({
  props: switchProps(),
  setup(props, { emit, attrs }) {
    console.log(props);

    
  },
});

output

image

expect

{modelValue: undefined, disabled: false}
@dwightjack
Copy link
Owner

@bosens-China I think this behavior is related to Vue boolean casting.

In your case, the undefined default value is cast to false.

@dwightjack dwightjack self-assigned this Jul 31, 2022
@bosens-China
Copy link
Author

But when I show it in the following way, it's OK

 modelValue: {
  type: Boolean,
  default: undefined
}

to

{modelValue: undefined, disabled: false}

@dwightjack
Copy link
Owner

dwightjack commented Aug 1, 2022

I see. In Vue, boolean props and nullable are always a gray area. At the moment .def(undefined) deletes the default property if present, so, changing this behavior might be a breaking change for other users.

You can, anyway, create a custom validator to fit your case:

import { bool, fromType } from 'vue-types';

const boolWithUndefined = () =>
  fromType('boolWithUndefined', bool, {
    default: undefined,
  });

export const switchProps = () => {
  return {
    modelValue: boolWithUndefined(),
    // ...
  };
};

@bosens-China
Copy link
Author

😭
Is it possible to force the behavior of def
I have explicitly specified "undefined" above

@dwightjack
Copy link
Owner

I took another look at the source code. It is probably an edge case related to the boolean type, so I think I could allow explicitly setting the default to undefined only for bool() 🤔.

@dwightjack
Copy link
Owner

After further investigation, I think this is a breaking change. I will keep the issue open and see if other users think this feature is useful (cc @victorgarciaesgi).

For the moment, the suggestion is to use a custom validator.

@bosens-China
Copy link
Author

#71

Found the same problem, I think it is still necessary, whether it is possible to determine the behavior of def by registering the global configuration

import { config } from 'vue-types'
config.mandatory = true;

@dwightjack dwightjack mentioned this issue Aug 8, 2022
2 tasks
@dwightjack
Copy link
Owner

Hi, I plan to release this change with version 5. At the moment I published it as a beta version: vue-types@5.0.0-beta.1.

let me know if it works as expected.

@dwightjack dwightjack removed the on hold label Aug 8, 2022
@bosens-China
Copy link
Author

test later,But can other types be forced to specify undefined this is in line with the official documentation

export const switchProps = () => {
  return {
    one: number().def(undefined),
    two: bool().def(undefined),
    three: string().def(undefined),
    // ... other
  };
};

@dwightjack
Copy link
Owner

If I understand correctly, boolean prop types are the only one where the value is casted if a default property is not defined. In all other cases, if the prop does not have a default property, the prop value is anyway undefined (https://github.com/vuejs/vue/blob/00458cd38d209410d3c675729230a42a0a34a4b9/src/core/util/props.ts#L70).

I think that the validators (used as named imports) does not force any sensible default, so assigned props should have a undefined value when nothing is passed.

Maybe I don't understand your use case. Could you provide an example with a couple of components?

@bosens-China
Copy link
Author

You're right

@bosens-China
Copy link
Author

<script >
import { defineComponent } from "vue";
import { number, string, object, array, func, bool } from "vue-types";

export default defineComponent({
  props: {
    test1: number().def(undefined),
    test2: string().def(undefined),
    test3: object().def(undefined),
    test4: array().def(undefined),
    test5: func().def(undefined),
    test6: bool().def(undefined),
  },
  setup(props) {
    console.log(props);
    return () => 123;
  },
});
</script>

test1: undefined
test2: undefined
test3: undefined
test4: undefined
test5: undefined
test6: undefined

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants