new·The score now tells you which way it movedA brain's exam only ever grows: its own material writes questions, and so does every question a real caller asked and did not get answered. The score is a percentage over that growing set, so a brain that learned more could post a smaller number — and this week three did. One of them answered two MORE questions than the week before and showed eighteen points less. Printed as a single percentage, that reads as decline to a reader and as punishment to anyone who contributes material.all news →
mozg.beta
Sign in

Vue · Guide · all subjects

components

198 notes in this subject, read out of this brain and free to use. This is page 4 of 4.

Vue custom elements support and compatibility

Vue scores a perfect 100% in the Custom Elements Everywhere tests. Vue has excellent support for both consuming and creating custom elements. Vue and Web Components are considered primarily complementary technologies.

Skipping component resolution for custom elements

By default, Vue attempts to resolve non-native HTML tags as registered Vue components before falling back to rendering them as custom elements. To skip this resolution and treat certain elements as custom elements, use the compilerOptions.isCustomElement option. This is a compile-time option that must be passed via build configs or app.config.compilerOptions.isCustomElement for in-browser compilation.

isCustomElement in-browser config example

For in-browser compilation: app.config.compilerOptions.isCustomElement = (tag) => tag.includes('-')

isCustomElement Vite config example

In vite.config.js, configure the Vue plugin to skip component resolution for custom elements: ```js import vue from '@vitejs/plugin-vue' export default { plugins: [ vue({ template: { compilerOptions: { isCustomElement: (tag) => tag.includes('-') } } }) ] } ```

isCustomElement Vue CLI config example

In vue.config.js, configure vue-loader to skip component resolution for custom elements: ```js module.exports = { chainWebpack: (config) => { config.module .rule('vue') .use('vue-loader') .tap((options) => ({ ...options, compilerOptions: { isCustomElement: (tag) => tag.startsWith('ion-') } })) } } ```

Passing DOM properties to custom elements

Vue 3 automatically checks for DOM-property presence using the 'in' operator when setting props on custom elements and prefers setting values as DOM properties if the key is present. In rare cases where data must be passed as a DOM property but the custom element does not properly define/reflect the property, use the .prop modifier or . shorthand to force the binding as a DOM property.

.prop modifier for custom element properties

Force a v-bind binding to be set as a DOM property using the .prop modifier: ```vue-html <my-element :user.prop="{ name: 'jack' }"></my-element> <!-- shorthand equivalent --> <my-element .user="{ name: 'jack' }"></my-element> ```

defineCustomElement creates custom element constructor

Use the defineCustomElement method to create custom elements using Vue component APIs. It accepts the same arguments as defineComponent but returns a custom element constructor that extends HTMLElement. defineCustomElement accepts standard Vue component options (props, emits, template) plus a styles option for CSS to be injected into the shadow root.

defineCustomElement example

```js import { defineCustomElement } from 'vue' const MyVueElement = defineCustomElement({ props: {}, emits: {}, template: `...`, styles: [`/* inlined css */`] }) // Register the custom element customElements.define('my-vue-element', MyVueElement) // Programmatically instantiate (after registration) document.body.appendChild( new MyVueElement({ // initial props (optional) }) ) ```

Component instance type extraction

To get the instance type of an imported component, use TypeScript's built-in InstanceType utility: `type FooType = InstanceType<typeof Foo>`. This can be used to type template refs for components.

ComponentPublicInstance for generic component refs

ComponentPublicInstance can be used to type component template refs when the exact component type isn't available or important. This type includes only properties shared by all components, such as `$el`: `const child = useTemplateRef<ComponentPublicInstance>('child')`.

Generic component template ref typing with ComponentExposed

When referencing a generic component with useTemplateRef, use ComponentExposed from the 'vue-component-type-helpers' library, as InstanceType does not work with generic components: `const modal = useTemplateRef<ComponentExposed<typeof MyGenericModal>>('modal')`. With @vue/language-tools 2.1+, static template refs' types can be automatically inferred.

defineComponent required for Options API TypeScript prop type inference

To enable type inference for props in Options API, you must wrap the component with defineComponent(). Without it, Vue cannot infer types for props based on the props option, including options like required: true and default.

Runtime props options only support constructor functions as types

The runtime props option only accepts constructor functions (like String, Number, Object, Function) as prop types. Complex types such as objects with nested properties or function call signatures cannot be specified directly at runtime.

PropType utility for typing complex component props

Use the PropType utility type from Vue to annotate complex prop types. Example: book: { type: Object as PropType<Book>, required: true } where Book is an interface. You can also use it with functions: callback: Function as PropType<(id: number) => void>.

TypeScript less than 4.7 requires arrow functions in prop validators and defaults

If using TypeScript version less than 4.7, you must use arrow functions for validator and default prop options to prevent type inference failure. This is because arrow functions prevent TypeScript from having to infer the type of 'this' inside these functions. This limitation was improved in TypeScript 4.7.

Example: PropType utility for complex object prop types

import { defineComponent } from 'vue' import type { PropType } from 'vue' interface Book { title: string author: string year: number } export default defineComponent({ props: { book: { type: Object as PropType<Book>, required: true }, callback: Function as PropType<(id: number) => void> }, mounted() { this.book.title // string this.book.year // number // TS Error: argument of type 'string' is not assignable to parameter of type 'number' this.callback?.('123') } })

Example: Arrow functions in prop validators for TypeScript < 4.7

import { defineComponent } from 'vue' import type { PropType } from 'vue' interface Book { title: string year?: number } export default defineComponent({ props: { bookA: { type: Object as PropType<Book>, // Make sure to use arrow functions if your TypeScript version is less than 4.7 default: () => ({ title: 'Arrow Function Expression' }), validator: (book: Book) => !!book.title } } })

Give your agent this brain