Reputation: 2644
I am trying to define components based on the prefix at the moment Vue parses the content (I am not using Vuex).
I found that Vue.config has a isUnknownElement
function but didn't find any documentation about it. Using this function I can execute Vue.component (with an async function) if the prefix matches, and I don't get the unknown component error, but the component is not rendered because the async function is not triggered. It will be triggered correctly the next time the tag is parsed.
The only solution I found so far to get it working is to render the component twice (putting it in a v-if and changing the variable it's bound to)
Does anyone know of a cleaner way?
Why doing this? In my apps, always SPA, I have a bunch of custom components all starting with the same prefix, and all with the same path architecture, so my component's name always correspond to its path (replacing dashes with slashes). It's why a global function to register on-demand each component starting with this prefix would come handy :)
Upvotes: 2
Views: 1075
Reputation: 31
I came here for the same reason as the OP, and I would like to share the solution I found.
It is based on the isUnknownElement
function mentioned, in addition to the following articles:
(1) https://v2.vuejs.org/v2/guide/components-dynamic-async.html#Async-Components
(2) https://forum.vuejs.org/t/why-use-the-no-function-in-vue-source-code-utils/27675
Vue.config.isUnknownElement = function () {
let tagName = arguments[0].toLowerCase();
if (/^vc-/i.test(tagName)) {
// Tag name like 'vc-*' is a VueJS component
// You need to check if the component is already defined:
// https://stackoverflow.com/questions/37389788/vue-js-check-if-a-component-exists
if (typeof Vue.options.components[tagName] === 'undefined') {
// register a lazy-loader for the component
// remove 'vc-' prefix from tagName to get the component's name
let componentName = tagName.substr(3);
Vue.component(tagName, function (resolve) {
// ... Load the component 'componentName' in a "lazy" way, see link (1)
});
}
}
return false; // Same behavior of the default Vue configuration, see link (2)
};
I have custom components identified by tags with the prefix 'vc-' (for example, 'vc-table'). In this manner, if Vue template compiler found a tag with the prefix, a component is defined dynamically and loaded in a lazy-load way.
Upvotes: 3
Reputation: 2644
I had found a solution too, and my components are autoloading now based on rules I define. I had the same approach than @dosorio but used a different function: isReservedTag
.
const isReservedTag = Vue.config.isReservedTag;
Vue.config.isReservedTag = (tag, context) => {
if ( isReservedTag(tag) ){
return true;
}
// Here I check if the tag match any of my rules
// If yes I define my component
if ( checkMyRule(tag) ){
Vue.component(tag, (resolve) => {
// Load the component
});
}
return false;
};
Upvotes: 0