You found this library and it does exactly what you need however you want to change a minor detail.
There's 2 options that comes to mind here:
In my previous article Vue - Overriding Third Party Defaults, we found out that default Props can be overridden. Just like props
, template
is just another key in a Vue component object.
Let us use vue-select as an example again.
In a previous project of mine, the client wanted a bit more of functionality from the vue-select. They wanted vue-select to:
The problem is although vue-select exposes a "transition" prop, it does not do what is needed. You can probably fake the sliding down by setting CSS max-height from 0 to 999px but it does not solve the going upwards problem.
There are many ways to solve this problem, one of them being the max-height trick, and for the going upwards, maybe just add some javascript on the containing component.
I decided to fix this in the root and also because I wanted to use VelocityJS for the sliding. So here's how I did it:
import VueSelect from 'vue-select'
import Velocity from 'velocity-animate'
const originalData = VueSelect.data
const originalRender = VueSelect.render
const originStateClasses = VueSelect.computed.stateClasses
VueSelect.computed.stateClasses = function() {
return {
'vs--upwards': this.upwards,
...originalStateClasses.call(this)
}
}
VueSelect.render = function(h) {
const rendered = originalRender.call(this, h)
const transitionComponent = rendered.children.find(c => {
return c.componentOptions && c.componentOptions.tag === 'transition'
})
transitionComponent.componentOptions.propsData = {
css: false
}
transitionComponent.componentOptions.listeners = {
enter: (el, done) => {
Velocity(el, "slideDown", {
duration: 300,
complete: done,
begin: () => {
const rect = el.getBoundingClientRect();
const withinViewPort = rect.top + rect.height < window.innerHeight
this.upwards = !withinViewPort
}
})
},
leave: (el, done) => {
Velocity(el, "slideUp", {
duration: 300,
complete: done
})
},
afterLeave: (el) => {
this.upwards = false
}
}
return rendered
}
First, I copied all the original properties that we're going to extend because otherwise we'll have to completely rewrite the same thing again, apart from the new stuff.
Next, I added another CSS class called vs--upwards
which I'm going to style when the dropdown goes upwards, and added all the original computed classes by appending the result of the original computed function.
We have to call the original function by doing originalFn.call(this)
instead of originalFn()
because we need to pass the context or "this".
Next, on the render function, we store the return value of the original render which would be a VNode. Read more.
Now we have the VNode that contains the original structure of the component or the part of a Vue SFC.
You didn't have to fork, and you got what you wanted in a couple lines of codes. Win-Win!
See the Pen Vue - Extending third-party component template by Lemuel Flores (@captainskippah) on CodePen.