-
Notifications
You must be signed in to change notification settings - Fork 546
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
prop "parse" function #107
Comments
Not saying this idea isn't viable, just trying to play devil's advocate. 😄
The trade off is, AFAIK, watchers should be mainly reserved for more asynchronous updating of the data. Not sure why your example prop parsing can't be done via computed props and why it isn't a simple decision to do so. Computeds are there for exactly that purpose. Parsing or rather recalculating values, which is what both your examples do. Sure, there is still the name clash issue of sorts. You just need to find a proper name for your computeds (and I'm not saying the ones below are great either 😁 ).
Or, since this is purely internal to the component, just put an underscore in front of the prop name. So The other, I believe, possibly viable alternative yet not wondrously great is offering a constructor function as the prop type, so outside of the component, the prop must be built via the constructor function. This constructor function can then also take over the parsing bit. That seems a bit more difficult though from a devland perspective, because it might not be clear upfront about how the prop needs to be "built via new" in order to pass the validation check. But, it should work (never done it myself to be honest). https://vuejs.org/v2/guide/components-props.html?#Type-Checks (the last bit about the constructor function). Scott |
This has been discussed previously in multiple issues, one of them is vuejs/vue#8049. By looking at the download stats of the package that implement such behavior, we can see that most people don't have the need, or at least do not suffer from using computed properties in order to justify adding a package to add such functionality. Among the problems you mention, the only one that exists is the need to have multiple names but ending up only using one (the sanitized version). Using a computed should always be the way to go, never a watcher that sets a data because those are meant for side effects while prop sanitation should be a pure function. |
@posva the package you mentioned does not look nearly as satisfying as the proposed feature. Also computed are not enough to deal with some props. Generally I imagine that props might follow much more flexible convention:
As mentioned by @mesqueeb the current implementation involves the definition of a local export default {
props: ['foo'],
data(){
// I need 'foo' properly formatted
let _foo = this.parseFoo(this.foo);
return {
_foo,
// 'bar' definition depends on the initial value of 'foo'
bar: !!_foo
}
},
watch: {
// I need '_foo' updated each time 'foo' changes
foo(){
// the following code line already exists in the `data()`
this.$data._foo = this.parseFoo(this.foo)
}
},
methods: {
parseFoo(){
return this.foo
},
updateFoo(val, sync){
// sometimes I update local value
// through updating parent's value
if( !sync )
return this.$data._foo = val;
// sometimes I don't want to affect the parent;
this.$emit('update:foo', val)
},
}
} Notice how we repeat code to set To me this non breaking feature looks neat and useful. Also I believe it is really easy to implement and is a matter of a just a few lines of code, so I hope the team finds it convenient. |
The only thing missing is being able to rename the prop, which is the only problem. There is an open issue for that btw: vuejs/vue#7943
I don't see how computed couldn't be enough. What are you thinking about Regarding the whole watcher thing, a computed property to derive data from a prop is the way to go. Watchers are for side effects, as mentioned in the previous comment |
Its not about what is missing in the package, Its about API design. The API it provides is not simple enough for the functionality it covers. |
It's about more than that to be fair but the API could be the same if the mentioned issue was implemented. It also shows more interest by the community and would allow the prop coercion feature to be implemented in user land to benefit those who prefer that syntax. The main reason prop coercion was removed is because it was redundant with computed properties |
In #78, @nekosaur said in this comment:
If I'm reading that correctly, in Vue 3 with the composition api, we'll be able to wrap props and return a new one with the same name without Vue raising an error. Can anyone confirm that? Something like this: createComponent({
props: {
foo: Number
},
setup (props) {
const foo = computed(() => props.foo * 2
// ❌ Vue 2 with composition api causes an error
// ❓ Vue 3 ...works?
return { foo }
} |
Though not mentioned in the description, I think it's worth noting that this suggestion would essentially solve the issue behind #106 |
I was originally in favor of this change, however after reading through #10 it seems to me too be a better solution (combined with a computed prop). As it keeps both the raw prop value, and the "parsed" value. export default {
props: {
name: {
type: String,
as: 'rawName'
},
},
computed: {
name() {
return titleCase(this.rawName)
}
}
} |
Yeah, agree. Parsing/ recalculation use computeds. Then implement the "as" solution for internal naming. 👍 Scott |
I think it would save a lot of boilerplate code if we could somehow transform props with a simple function defined right in the props configuration.
Eg. a function called
parse
could be executed before props are passed tosetup(props)
and before the props are registered onthis
The current implementation is:
The main problems are:
nameParsed
computed
anddata
+watch
)A simple
parse
function to be defined in the prop config seems like a very valuable addition. It's easy to understand and not breaking; so backwards compatible.The text was updated successfully, but these errors were encountered: