Closed ChristianKienle closed 5 years ago
This is the (untested) workaround we are currently using:
/**
* For context see below.
* @param {import("@vuese/parser").SlotResult} lhsSlot
* @param {import("@vuese/parser").SlotResult} rhsSlot
* @returns {import("@vuese/parser").SlotResult}
*/
const mergedSlot = (lhsSlot, rhsSlot) => {
const name = lhsSlot.name;
const { describe: lhsDescribe, backerDesc: lhsBackerDesc, bindings: lhsBindings, scoped: lhsScoped } = lhsSlot;
const { describe: rhsDescribe, backerDesc: rhsBackerDesc, bindings: rhsBindings, scoped: rhsScoped } = rhsSlot;
const describe = lhsDescribe.length >= rhsDescribe.length ? lhsDescribe : rhsDescribe;
const backerDesc = lhsBackerDesc.length >= rhsBackerDesc.length ? lhsBackerDesc : rhsBackerDesc;
const bindings = Object.keys(lhsBindings).length >= Object.keys(rhsBindings).length ? lhsBindings : rhsBindings;
// The default seems to be 'false' – so if lhsScoped is true we take that. Otherwise we simply use rhsScoped
const scoped = lhsScoped === true ? true : rhsScoped;
return { scoped, name, describe, backerDesc, bindings };
};
/**
* For context see below.
* @param {import("@vuese/parser").SlotResult} slot
* @param {import("@vuese/parser").SlotResult[]} otherSlots
* @returns {import("@vuese/parser").SlotResult}
*/
const fixedSlot = (slot, otherSlots) => {
const duplicateSlots = otherSlots.filter(({ name }) => name === slot.name);
if(duplicateSlots.length === 0) {
return slot; // no duplicates – phew
}
let fixed = slot;
duplicateSlots.forEach(otherSlot => {
fixed = mergedSlot(fixed, otherSlot);
});
return fixed;
};
/**
* For context see fixedParserResult below.
* @param {import("@vuese/parser").SlotResult[]} slots
* @returns {import("@vuese/parser").SlotResult[]}
*/
const fixedParserSlots = slots => {
const fixedButDuplicated = slots.map((slot, index) => {
const otherSlots = [...slots];
// remove the current slot from the copy
// the result are the 'other slots'
otherSlots.splice(index, 1);
return fixedSlot(slot, otherSlots);
});
// fixedButDuplicated now contains correct slots but duplicated still remain.
const result = [];
fixedButDuplicated.forEach(slot => {
const alreadyInResult = result.findIndex(resultSlot => resultSlot.name === slot.name) >= 0;
if(alreadyInResult) {
return;
}
result.push(slot);
});
return result;
};
/**
* Fixes the parser result. There is currently a bug in @vuese/parser
* which causes result.slots to contain duplicate entries.
* See: https://github.com/vuese/vuese/issues/83
* @param {import("@vuese/parser").ParserResult} result
* @returns {import("@vuese/parser").ParserResult}
*/
const fixedParserResult = result => {
const { slots = [] } = result;
return { ...result, slots: fixedParserSlots(slots) };
};
Just use:
Thank you very much. You are awesome. :)
Describe the bug If the template contains a named slot
<slot name="back" />
is will be part of the slot-parser result. That is fine. However, if your script contains$slots.back
it will appear twice.To Reproduce Steps to reproduce the behavior: Paste the following snippet into the explorer:
Expected behavior I expect the slots-array to only contain a single entry.
Which version do you use: latest
Additional information FYI: I have noticed that the unit tests don't fail because the count is not checked...
Btw: Fundamental Vue is adopting Vuese right now. :) We will slowly transition to Vuese in order to make our manually managed API-documentation obsolete.