@@ -293,110 +293,110 @@ customElements.define('some-element', SomeElement)
293293// 将新元素类型添加到 Vue 的 GlobalComponents 类型中。
294294declare module ' vue' {
295295 interface GlobalComponents {
296- // 请务必在此处输入 Vue 组件类型(SomeComponent,*而不是* SomeElement)。
297- // 自定义元素的名称中需要连字符,因此请在此处使用连字符元素名称。
296+ // 请务必在此处输入 Vue 组件类型
297+ // (SomeComponent,*而不是* SomeElement)。
298+ // 自定义元素的名称中需要连字符,
299+ // 因此请在此处使用连字符元素名称。
298300 ' some-element' : typeof SomeComponent
299301 }
300302}
301303```
302304
303305## 非 Vue Web Components 和 TypeScript {#non-vue-web-components-and-typescript}
304- <!-- TODO: translation -->
305- Here is the recommended way to enable type checking in SFC templates of Custom
306- Elements that are not built with Vue.
306+
307+ 以下是在非 Vue 构建的自定义元素的 SFC 模板中启用类型检查的推荐方法。
307308
308309> [ !Note]
309- > This approach is one possible way to do it, but it may vary depending on the
310- > framework being used to create the custom elements.
310+ > 这种方法是实现该功能的一种可能方式
311+ > 但具体实现可能因创建自定义元素所用的框架而异。
311312
312- Suppose we have a custom element with some JS properties and events defined, and
313- it is shipped in a library called ` some-lib ` :
313+ 假设我们有一个自定义元素,其中定义了一些 JS 属性和事件,并且它发布在名为 ` some-lib ` 的库中:
314314
315315``` ts
316316// file: some-lib/src/SomeElement.ts
317317
318- // Define a class with typed JS properties.
318+ // 定义一个带有类型化 JS 属性的类
319319export class SomeElement extends HTMLElement {
320320 foo: number = 123
321321 bar: string = ' blah'
322322
323323 lorem: boolean = false
324324
325- // This method should not be exposed to template types.
325+ // 这个方法不应该暴露给模板类型
326326 someMethod() {
327327 /* ... */
328328 }
329329
330- // ... implementation details omitted ...
331- // ... assume the element dispatches events named "apple-fell" ...
330+ // ... 省略实现细节 ...
331+ // ... 假设元素会分派名为 "apple-fell" 的事件 ...
332332}
333333
334334customElements .define (' some-element' , SomeElement )
335335
336- // This is a list of properties of SomeElement that will be selected for type
337- // checking in framework templates (f.e. Vue SFC templates). Any other
338- // properties will not be exposed.
336+ // 这是一个包含 SomeElement 属性列表的类型定义
337+ // 这些属性将用于框架模板 (如 Vue SFC 模板 的类型检查
338+ // 其他属性将不会暴露
339339export type SomeElementAttributes = ' foo' | ' bar'
340340
341- // Define the event types that SomeElement dispatches.
341+ // 定义 SomeElement 分派的事件类型
342342export type SomeElementEvents = {
343343 ' apple-fell' : AppleFellEvent
344344}
345345
346346export class AppleFellEvent extends Event {
347- /* ... details omitted ... */
347+ /* ... 省略细节 ... */
348348}
349349```
350350
351- The implementation details have been omitted, but the important part is that we
352- have type definitions for two things: prop types and event types.
351+ 实现细节已省略,重点是我们为两个东西提供了类型定义:prop 类型和事件类型。
353352
354- Let's create a type helper for easily registering custom element type
355- definitions in Vue:
353+ 让我们创建一个类型工具,以便在 Vue 中轻松注册自定义元素类型定义:
356354
357355``` ts
358356// file: some-lib/src/DefineCustomElement.ts
359357
360- // We can re-use this type helper per each element we need to define.
358+ // 我们可以为每个需要定义的元素重复使用这个类型助手
361359type DefineCustomElement <
362360 ElementType extends HTMLElement ,
363361 Events extends EventMap = {},
364362 SelectedAttributes extends keyof ElementType = keyof ElementType
365363> = new () => ElementType & {
366- // Use $props to define the properties exposed to template type checking. Vue
367- // specifically reads prop definitions from the `$props` type. Note that we
368- // combine the element's props with the global HTML props and Vue's special
369- // props.
370- /** @deprecated Do not use the $props property on a Custom Element ref, this is for template prop types only. */
364+ // 使用 $props 定义暴露给模板类型检查的属性
365+ // Vue 特别从 `$props` 类型读取属性定义
366+ // 请注意,我们将元素的属性与全局 HTML 属性和 Vue 的特殊属性结合在一起
367+
368+ /** @deprecated 不要在自定义元素引用上使用 $props 属性,
369+ 这仅用于模板属性类型检查 */
371370 $props: HTMLAttributes &
372371 Partial <Pick <ElementType , SelectedAttributes >> &
373372 PublicProps
374373
375- // Use $emit to specifically define event types. Vue specifically reads event
376- // types from the `$emit` type. Note that `$emit` expects a particular format
377- // that we map `Events` to.
378- /** @deprecated Do not use the $emit property on a Custom Element ref, this is for template prop types only. */
374+ // 使用 $emit 专门定义事件类型
375+ // Vue 特别从 `$emit` 类型读取事件类型
376+ // 请注意,`$emit` 期望我们将 `Events` 映射到特定格式
377+ /** @deprecated 不要在自定义元素引用上使用 $emit 属性,
378+ 这仅用于模板属性类型检查 */
379379 $emit: VueEmit <Events >
380380}
381381
382382type EventMap = {
383383 [event : string ]: Event
384384}
385385
386- // This maps an EventMap to the format that Vue's $emit type expects.
386+ // 这将 EventMap 映射到 Vue 的 $emit 类型期望的格式
387387type VueEmit <T extends EventMap > = EmitFn <{
388388 [K in keyof T ]: (event : T [K ]) => void
389389}>
390390` ` `
391391
392392> [!Note]
393- > We marked ` $props ` and ` $emit ` as deprecated so that when we get a ` ref ` to a
394- > custom element we will not be tempted to use these properties, as these
395- > properties are for type checking purposes only when it comes to custom elements.
396- > These properties do not actually exist on the custom element instances.
393+ > 我们将 ` $props ` 和 ` $emit ` 标记为已弃用,
394+ > 以便当我们获取自定义元素的 ` ref ` 时,我们不会被诱导使用这些属性,
395+ > 因为这些属性在自定义元素的情况下仅用于类型检查。
396+ > 这些属性实际上并不存在于自定义元素实例上。
397+
398+ 使用类型助手,我们现在可以选择在 Vue 模板中应暴露的 JS 属性进行类型检查:
397399
398- Using the type helper we can now select the JS properties that should be exposed
399- for type checking in Vue templates:
400400
401401` ` ` ts
402402// file: some-lib/src/SomeElement.vue.ts
@@ -409,7 +409,7 @@ import {
409409import type { Component } from ' vue'
410410import type { DefineCustomElement } from ' ./DefineCustomElement'
411411
412- // Add the new element type to Vue's GlobalComponents type.
412+ // 将新元素类型添加到 Vue 的 GlobalComponents 类型中
413413declare module ' vue' {
414414 interface GlobalComponents {
415415 ' some-element' : DefineCustomElement <
@@ -421,17 +421,16 @@ declare module 'vue' {
421421}
422422```
423423
424- Suppose that ` some-lib ` builds its source TypeScript files into a ` dist/ ` folder. A user of
425- ` some-lib ` can then import ` SomeElement ` and use it in a Vue SFC like so:
424+ 假设 some-lib 将其 TypeScript 源文件构建到 dist/ 文件夹中。some-lib 的用户可以像这样导入 SomeElement 并在 Vue SFC 中使用它:
426425
427426``` vue
428427<script setup lang="ts">
429- // This will create and register the element with the browser.
428+ // 这将创建并在浏览器中注册元素
430429import 'some-lib/dist/SomeElement.js'
431430
432- // A user that is using TypeScript and Vue should additionally import the
433- // Vue-specific type definition (users of other frameworks may import other
434- // framework-specific type definitions).
431+ // 使用 TypeScript 和 Vue 的用户应另外导入 Vue 特定的类型定义
432+ //(使用其他框架的用户可以导入其他框架特定的类型定义)
433+
435434import type {} from 'some-lib/dist/SomeElement.vue.js'
436435
437436import { useTemplateRef, onMounted } from 'vue'
@@ -446,37 +445,38 @@ onMounted(() => {
446445 el.value!.someMethod()
447446 )
448447
449- // Do not use these props, they are `undefined` (IDE will show them crossed out):
448+ // 不要使用这些属性,它们是 `undefined`
449+ // IDE 会将它们显示为删除线
450450 el.$props
451451 el.$emit
452452})
453453</script>
454454
455455<template>
456- <!-- Now we can use the element, with type checking: -->
456+ <!-- 现在我们可以使用这个元素,并进行类型检查: -->
457457 <some-element
458458 ref="el"
459459 :foo="456"
460460 :blah="'hello'"
461461 @apple-fell="
462462 (event) => {
463- // The type of `event` is inferred here to be `AppleFellEvent`
463+ // 这里 `event` 的类型被推断为 `AppleFellEvent`
464464 }
465465 "
466466 ></some-element>
467467</template>
468468```
469469
470- If an element does not have type definitions, the types of the properties and events can be
471- defined in a more manual fashion:
470+ 如果一个元素没有类型定义,可以通过更手动的方式定义属性和事件的类型:
471+
472472
473473``` vue
474474<script setup lang="ts">
475- // Suppose that `some-lib` is plain JS without type definitions, and TypeScript
476- // cannot infer the types:
475+ // 假设 `some-lib` 是纯 JavaScript,没有类型定义,并且 TypeScript 无法推断类型:
476+
477477import { SomeElement } from 'some-lib'
478478
479- // We'll use the same type helper as before.
479+ // 我们将使用之前相同的类型助手
480480import { DefineCustomElement } from './DefineCustomElement'
481481
482482type SomeElementProps = { foo?: number; bar?: string }
@@ -485,7 +485,7 @@ interface AppleFellEvent extends Event {
485485 /* ... */
486486}
487487
488- // Add the new element type to Vue's GlobalComponents type.
488+ // 将新元素类型添加到 Vue 的 GlobalComponents 类型中
489489declare module 'vue' {
490490 interface GlobalComponents {
491491 'some-element': DefineCustomElement<
@@ -495,19 +495,15 @@ declare module 'vue' {
495495 }
496496}
497497
498- // ... same as before, use a reference to the element ...
498+ // ... 与之前相同,使用元素引用 ...
499499</script>
500500
501501<template>
502- <!-- ... same as before, use the element in the template ... -->
502+ <!-- ... 与之前相同,在模板中使用元素 ... -->
503503</template>
504504```
505505
506- Custom Element authors should not automatically export framework-specific custom
507- element type definitions from their libraries, for example they should not
508- export them from an ` index.ts ` file that also exports the rest of the library,
509- otherwise users will have unexpected module augmentation errors. Users should
510- import the framework-specific type definition file that they need.
506+ 自定义元素的作者不应该从他们的库中自动导出特定框架的自定义元素类型定义,例如他们不应该同时从 ` index.ts ` 文件中导出它们以及库的其余部分,否则用户将会遇到意外的模块扩展错误。用户应该导入他们需要的特定框架的类型定义文件。
511507
512508## Web Components vs. Vue Components {#web-components-vs-vue-components}
513509
0 commit comments