-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: use vue 3 global and composition api in ix-img
This commit refactors the component into a functional component to remove the vue-class-component dependency. This is necessary because the dependency has not updated their release candidate for vue 3 support in months. Furthermore, functional components are quickly becoming the more idiomatic way to write components in vue 3. This commit also refactors the component to use the new global defineComponent api and h composition api. The defineComponent api exposes a new function, the setup function, that replaces a lot of the functionality previously done in the render function. Setup can accepts props as an argument. Setup can also return its own render function. The new render function for defineComponent does not accept arguments. And, rather than aliasing createElement to h, vue now directly exports h as a function which can be used inside the render function.
- Loading branch information
Showing
1 changed file
with
43 additions
and
43 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,67 +1,67 @@ | ||
import { ensureVueImgixClientSingleton, IVueImgixClient } from './vue-imgix'; | ||
import Vue, { CreateElement } from 'vue'; | ||
import Component from 'vue-class-component'; | ||
import { ensureVueImgixClientSingleton } from './vue-imgix'; | ||
import { h, defineComponent } from 'vue'; | ||
|
||
const IxImgProps = Vue.extend({ | ||
props: { | ||
src: { | ||
type: String, | ||
required: true, | ||
}, | ||
fixed: Boolean, | ||
imgixParams: Object, | ||
width: [String, Number], | ||
height: [String, Number], | ||
attributeConfig: Object, | ||
disableVariableQuality: Boolean, | ||
const IxImgProps = { | ||
src: { | ||
type: String, | ||
required: true, | ||
}, | ||
}); | ||
fixed: Boolean, | ||
imgixParams: Object, | ||
width: [String, Number], | ||
height: [String, Number], | ||
attributeConfig: Object, | ||
disableVariableQuality: Boolean, | ||
sizes: [String], | ||
// TODO(luis): remove dataTestId props in favor of a better solution | ||
dataTestId: { | ||
type: String, | ||
required: false, | ||
} | ||
}; | ||
|
||
const defaultAttributeMap = { | ||
src: 'src', | ||
srcset: 'srcset', | ||
}; | ||
|
||
@Component | ||
export class IxImg extends IxImgProps { | ||
// Using !: here because we ensure it is set in created() | ||
private vueImgixSingleton!: IVueImgixClient; | ||
|
||
created() { | ||
this.vueImgixSingleton = ensureVueImgixClientSingleton(); | ||
} | ||
export const IxImg = defineComponent({ | ||
props: IxImgProps, | ||
|
||
render(createElement: CreateElement) { | ||
setup(props) { | ||
const vueImgixSingleton = ensureVueImgixClientSingleton(); | ||
const imgixParamsFromImgAttributes = { | ||
...(this.fixed && { | ||
...(this.width != null ? { w: this.width } : {}), | ||
...(this.height != null ? { h: this.height } : {}), | ||
...(props.fixed && { | ||
...(props.width != null ? { w: props.width } : {}), | ||
...(props.height != null ? { h: props.height } : {}), | ||
}), | ||
}; | ||
|
||
const { src, srcset } = this.vueImgixSingleton.buildUrlObject( | ||
this.src, | ||
const { src, srcset } = vueImgixSingleton.buildUrlObject( | ||
props.src as string, | ||
{ | ||
...imgixParamsFromImgAttributes, | ||
...this.imgixParams, | ||
...props.imgixParams, | ||
}, | ||
{ | ||
disableVariableQuality: Boolean(this.disableVariableQuality), | ||
disableVariableQuality: Boolean(props.disableVariableQuality), | ||
}, | ||
); | ||
|
||
const attributeConfig = { | ||
...defaultAttributeMap, | ||
...this.attributeConfig, | ||
...props.attributeConfig, | ||
}; | ||
|
||
return createElement('img', { | ||
attrs: { | ||
[attributeConfig.src]: src, | ||
[attributeConfig.srcset]: srcset, | ||
width: this.width, | ||
height: this.height, | ||
}, | ||
}); | ||
} | ||
} | ||
return () => | ||
h('img', { | ||
[attributeConfig.src]: src, | ||
[attributeConfig.srcset]: srcset, | ||
width: props.width, | ||
height: props.height, | ||
sizes: props.sizes, | ||
// TODO(luis): remove dataTestId props in favor of a better solution | ||
['data-testid']: props.dataTestId || undefined, | ||
}); | ||
}, | ||
}); |