-
-
Notifications
You must be signed in to change notification settings - Fork 33.7k
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
feat(core): support passing down scopedSlots with v-bind #7765
Conversation
Btw, this is still open to discussion, since the syntax isn't entirely consistent. You can do Internally So alternatively, we can expose a special convention for This then allows the usage: <child v-bind="{ $scopedSlots } /> In addition, if you know the underlying VNode data interface, you can also do low-level stuff without dropping into render functions: <child v-bind="{
$on: {
someEvent: someMethod
},
$nativeOn: {
click: someMethod
}
}"/> |
What about adding a dedicated directive for merging vnode data? Since If we have such directive we can simply write the vnode data as the same shape as in render function (named it <child v-vnode="{
scopedSlots: $scopedSlots,
on: {
someEvent: someMethod
},
nativeOn: {
click: someMethod
}
}"/> We may write directive argument like <child v-vnode:scoped-slots="$scopedSlots" /> This also has a benefit that we may able to write template type checker for that as we can simply utilize Vue's typescript typings. (FYI: The current WIP implementation of template type checker is here) |
The specific directive proposed by @ktsn seems a little awkward to me, but I think it would make sense to separate the behavior to improve readability. |
What's the status of this? |
So is there a consensus on using a different tag name or not? If so, what should it be called? Otherwise, this is clearly a hangup for a lot of people using Vue (googling led me to 5-6 different issues on the same topic) and it'd be nice to either give this a thumbs up or have some direction in what needs to be done to get this shipped. As an added note, the current "solution" of using a |
I wouldn't recommend this solution, but I needed this functionality now - so I implemented @yyx990803 's change as a plugin: var BindScopedSlotsPlugin = {
install: function(Vue, options) {
Vue.prototype._b = function bindObjectProps (
data,
tag,
value,
asProp,
isSync
) {
if (value) {
if (value === null || typeof value !== 'object') {
warn(
'v-bind without argument expects an Object or Array value',
this
);
} else {
if (Array.isArray(value)) {
var res = {};
for (var i = 0; i < value.length; i++) {
if (value[i]) {
Vue.util.extend(res, value[i]);
}
}
value = res;
}
var hash;
var loop = function ( key ) {
if (
key === 'class' ||
key === 'style' ||
key === 'scopedSlots' || // new code
Vue.config.isReservedAttr(key)
) {
hash = data;
} else {
var type = data.attrs && data.attrs.type;
hash = asProp || Vue.config.mustUseProp(tag, type, key)
? data.domProps || (data.domProps = {})
: data.attrs || (data.attrs = {});
}
if (!(key in hash)) {
hash[key] = value[key];
if (isSync) {
var on = data.on || (data.on = {});
on[("update:" + key)] = function ($event) {
value[key] = $event;
};
}
}
};
for (var key in value) loop( key );
}
}
return data;
};
}
};
Vue.use( BindScopedSlotsPlugin ); The syntax is as mentioned initially: |
@ClickerMonkey thanks for building the plugin! there is a tiny typo: |
Thanks! I have a smaller simpler version: Vue.prototype._b = (function (bind) {
return function(data, tag, value, asProp, isSync) {
if (value && value.$scopedSlots) {
data.scopedSlots = value.$scopedSlots;
delete value.$scopedSlots;
}
return bind.apply(this, arguments);
};
})(Vue.prototype._b); And you just need to add |
Check out this solution too: https://stackoverflow.com/a/52823029/2050460 |
Added another test to ensure default slot contents are preserved as well as slots passed to children.
I edited the @ClickerMonkey script to merge the parent and the current $scopedSlots, maybe it can be useful for someone
|
So I don't think we will land this, because:
<foo :slots="$slots"></foo> Moreover, we have other changes in v3 that makes passing things down to child components easier (RFC in early 2019). |
Glad to hear about v3. Thanks Evan for everything! |
Started with the granular slots (inside the Search / Preview components), but it appears that fallback content is not rendered in the nested slots in vue 2.5. It works in 2.6 and should be further improved in 3.0, see vuejs/vue#7765 (comment)
adds a shim for bindObjectProps as in vuejs/vue#7765
So, there is no reserved |
Started with the granular slots (inside the Search / Preview components), but it appears that fallback content is not rendered in the nested slots in vue 2.5. It works in 2.6 and should be further improved in 3.0, see vuejs/vue#7765 (comment)
Allow passing down scoped slots using
v-bind
:close #7178, close #7351