-
Notifications
You must be signed in to change notification settings - Fork 915
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
[Feature] Component composition with higher-order components in .vue files #723
Comments
If a practical use case for this is needed i'll try to provide one: As a user i want to connect my form-fields to Vuex via a HOC to avoid having local state. I make a custom component called
The This won't work as it is today. The user would have to create a separate file where he/she uses Imagine if the user had several of these components:
For each of these components the user would have to create two files, even if it adds no additional value. I personally feel that this adds unwanted complexity to do something so trivial as to create a HOC. I'm not sure how we would solve this problem and would be happy to hear some ideas! |
I'm also interested in HoC's via single file components and just finished digging through vue-loader and some related code - I don't see how this could be accomplished with a sensible API. Currently vue-loader assumes the whole component is the vue file. My understanding of what you're asking is for some way to declare in your <script> what represents your current component and what's wrapping it, and I can't think of a sensible way to accomplish that. e.g. in your example what's to say |
IMHO this would be a great feature. From a short look into the vue-loader I would say the following would be at least a simple solution.
// check, if hocs should be loaded
if (options.hoc) {
// allow to be used like { hoc: withA } as well as { hoc: [ withA, withB ] }
if (!Array.isArray(options.hoc)) {
options.hoc = [options.hoc];
}
if (typeof scriptExports === "function") {
throw new Error(`Loading vue HOCs not yet supported for Vue.extend`);
}
// just inserted compose here for readability, doesn't have to be in scope of normalizeComponent
const compose = stages => Component => stages
.reverse()
.reduce((result, fn, i) => {
if (typeof fn !== "function") {
throw new Error(`Expected HOC to be function, got ${typeof fn} for element #${i}`);
}
return fn(result);
},
Component
);
const enhance = compose(options.hoc);
scriptExports = enhance(scriptExports);
options = scriptExports;
} ➕easy to develop Another great feature would be to pass a post-processing function with the webpack options. That function would be called with the parsed component and could implement logic like above. |
From the looks of it, it's not possible to use HOC's in
.vue
files because of the wayvue-loader
loader works. Instead you have to apply your HOC in a.js
file.In, for instance, React+Redux containers you would usually define your component and and "connect" it to the store using a HOC from the react-redux package. It could look something like this:
When trying to do something similar with
.vue
files the render function of the HOC gets replaced instead of the render function of the component you're applying your HOC to.The following code will cause
vue-loader
to replace the render function of the component returned byconnect
instead of replacing the render function ofMyComponent
:To work around this you can, in your
.vue
, export MyComponent and have a.js
which exports the connectedMyComponent
, but i find it unnecessarily complicated.tl;dr
I want to be able to better reuse code with higher-order functions in Vue, the way you do in e.g. React.
The text was updated successfully, but these errors were encountered: