v-bind support binding multiple objects
sqal opened this issue · 7 comments
What problem does this feature solve?
Currently, if we want to pass attributes from multiple sources we have to manually import mergeProps
helper and do
<MyComponent v-bind="mergeProps($attrs, featAProps, featBProps)" />
or use computed property
It would be better if we could just do:
<script setup>
const featAProps = useFeatureA()
const featBProps = useFeatureB()
</script>
<template>
<MyComponent v-bind="[$attrs, featAProps, featBProps]" />
</template>
What does the proposed API look like?
Allow passing an array of props to v-bind v-bind="[x,y,..]"
Currently most scripts use {...$attrs, ...featAProps, ...featBProps}
Is it really neccessary to introduce the array form?
I agree, I don't think we need to add another variation to this API.
@posva I think this is not a issue...
we have native ES syntax for combining multiple objects
{...$attrs, ...featAProps, ...featBProps}
I think this issue can be closed.
@cyfung1031 using spread operator or Object.assing would result in overriding props instread of merging them. What if featAProps have onClick/class and featBProps as well? that's why you have to use mergeProps
@cyfung1031 using spread operator or Object.assing would result in overriding props instread of merging them. What if featAProps have onClick/class and featBProps as well? that's why you have to use mergeProps
This is another issue. You are not asking for binding multiple objects. You are asking for binding multiple methods to the same attribute in the same component.
You should open another issue for this. They are different.
The working principle for v-bind
is based on the key-value relationship.
This seems to be supported (accidentally?) only if you have other attributes bound too.
// Works
<MyComponent foo="bar" v-bind="$attrs, featAProps, featBProps" />
// Doesn't
<MyComponent v-bind="$attrs, featAProps, featBProps" />
This is because attributes + v-bind is compiled directly to a mergeProps
call:
_createBlock(_component_MyComponent, _mergeProps({ foo: "bar" }, _ctx.$attrs, _ctx.featAProps, _ctx.featBProps), null, 16 /* FULL_PROPS */)
But v-bind
alone uses guardReactiveProps
instead which only accepts a single argument:
_createBlock(_component_MyComponent, _normalizeProps(_guardReactiveProps(_ctx.$attrs, _ctx.featAProps, _ctx.featBProps)), null, 16 /* FULL_PROPS */)
Related: vuejs/eslint-plugin-vue#1731
This seems to be supported (accidentally?) only if you have other attributes bound too.
// Works <MyComponent foo="bar" v-bind="$attrs, featAProps, featBProps" /> // Doesn't <MyComponent v-bind="$attrs, featAProps, featBProps" />This is because attributes + v-bind is compiled directly to a
mergeProps
call:_createBlock(_component_MyComponent, _mergeProps({ foo: "bar" }, _ctx.$attrs, _ctx.featAProps, _ctx.featBProps), null, 16 /* FULL_PROPS */)But
v-bind
alone usesguardReactiveProps
instead which only accepts a single argument:_createBlock(_component_MyComponent, _normalizeProps(_guardReactiveProps(_ctx.$attrs, _ctx.featAProps, _ctx.featBProps)), null, 16 /* FULL_PROPS */)Related: vuejs/eslint-plugin-vue#1731
Is this still considered a bug or is it a feature? It seems to still work in Vue 3 without any errors and I only have a separate class
attribute on it, not even a prop