Skip to content

Commit a71a63f

Browse files
committed
fix: add scene
1 parent 824ea5d commit a71a63f

File tree

1 file changed

+64
-23
lines changed

1 file changed

+64
-23
lines changed

active-rfcs/0000-infer-attrs.md

+64-23
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
- Start Date: 2023-01-01
22
- Target Major Version: 3.x
3-
- Reference Issues: [vuejs/core#3452](https://github.com/vuejs/core/issues/3452), [vuejs/core#5423](https://github.com/vuejs/core/issues/5423),
3+
- Reference Issues: [vuejs/core#3452](https://github.com/vuejs/core/issues/3452), [vuejs/core#5423](https://github.com/vuejs/core/issues/5423), [vuejs/core#6528](https://github.com/vuejs/core/discussions/6528)
44
- Implementation PR: [vuejs/core#7444](https://github.com/vuejs/core/pull/7444)
55

66
# Summary
@@ -12,7 +12,7 @@ I already published an npm package named [vue-ts-utils](https://github.com/rudy-
1212
# Basic example
1313

1414
## Using `defineComponent`
15-
[TS Playground](https://www.typescriptlang.org/play?jsx=1#code/JYWwDg9gTgLgBAbzgEwKYDNgDtUGELgQ5bwC+c6UBcA5AG4CuqAtDAM7MMzAA2bNAWABQwgMZE28fODgBeFBmx4CkYjAAUCYXDhgqYNgC5E2nRQgRjAZRhRsAcwA0p0s6E6oqLGijqAlIikwq6IcACGMLZGgeFsoQBGYVDGWAwg8ahQcOSkfsJiEvDiMvIAPNJg5hCyCDQAjDTkiVA1deQA9AB8wkA)
15+
[TS Playground](https://www.typescriptlang.org/play?jsx=1#code/JYWwDg9gTgLgBAbzgEwKYDNgDtUGELgQ5bwC+c6UBcA5AG4CuqAtDAM7MMzAA2bNAWABQwgMZE28fODgBeFBmx4CkYjAAUCYXDhgqYNgC5E2nRQgRjAZRhRsAcwA0p0s6E6oqLGijqAlIikwq6IcACGMLZGgeFsoQBGYVDGWAwg8ahQcOSkfsJiEvDiMvIAPNJg5hCyCDQAjDTkiVA1deQA9AB8wkA) with Options Api
1616
```tsx
1717
const Comp = defineComponent({
1818
props: {
@@ -27,32 +27,59 @@ const Comp = defineComponent({
2727
const comp = <Comp foo={'str'} bar={1} />
2828
```
2929

30-
## Using `useAttrs<T>` in `script-setup`
30+
[TS Playground](https://www.typescriptlang.org/play?jsx=1#code/JYWwDg9gTgLgBAbzgEwKYDNgDtUGELgQ5bwC+c6UBcA5AG4CuqAtDAM7MMzAA2bNAWABQwgMZE28fODgBeFBmx4CkYjAAUCYXDhgqYNgC5E2nRQgRjAZRhRsAcwA0p0s6E62qGAzDq9EA0dEOABDGFs2OFIAShN3M3EsNggeVAA6Hgh7P302NPQLWIB6IrhJOyx7Ux1E5NSMrPUwiLSAIxCoYtKsBhBW1CgXYVdg5qgjRHIQyKR2qGMevoGoqOjhMQl4cRl5AB5pMHMIWQQaAEYacjmTs-IigD5hIA) with Composition Api
31+
```tsx
32+
const Comp = defineComponent({
33+
props: {
34+
foo: String
35+
},
36+
setup(props, { attrs }) {
37+
// number
38+
console.log(attrs.bar)
39+
}
40+
}, { attrs: {} as { bar: number } })
3141

32-
```vue
33-
<script setup lang="ts">
34-
const attrs = useAttrs<{bar: number}>()
35-
</script>
42+
const comp = <Comp foo={'str'} bar={1} />
3643
```
3744

38-
<details>
39-
<summary>Compiled Output</summary>
4045

41-
```js
42-
export default /*#__PURE__*/_defineComponent({
43-
setup(__props, { expose }) {
44-
expose();
46+
[TS Playground](https://www.typescriptlang.org/play?jsx=1#code/JYWwDg9gTgLgBAbzgEwKYDNgDtUGELgQ5bwC+c6UBcA5AG4CuqAtDAM7MMzAA2bNAWABQwgMZE28fODgBeFBmx4CkYjAAUCYXDhgqYNgC5E2nRQgRjAZRhRsAcwA0p0s6E62qGAzDq9EA0dEOABDGFs2OFIAShN3M3EsNggeVAA6Hgh7P302NPQLWIB6IrhJOyx7Ux1E5NSMrPUwiLSAIxCoYtKsBhBW1CgXYVdg5qgjRHIQyKR2qGMevoGoqOjhMQl4cRl5AB5pMHMIWQQaAEYacjmTs-IigD5hIA) with functional Components
47+
```tsx
48+
import { defineComponent, h, type SetupContext } from 'vue'
4549

46-
const attrs = useAttrs<{ foo: number }>()
50+
type CompAttrs = {
51+
bar: number
52+
baz?: string
53+
}
4754

48-
return { attrs, useAttrs, ref }
55+
type CompEmits = {
56+
change: (val: string) => void;
4957
}
5058

51-
}, { attrs: {} as { foo: number }})"
59+
const MyComp = defineComponent(
60+
(_props: { foo: string }, ctx: SetupContext<CompEmits, CompAttrs>) => {
61+
// number
62+
console.log(ctx.attrs.bar)
63+
// string | undefined
64+
console.log(ctx.attrs.baz)
65+
66+
ctx.emit('change', '1')
67+
68+
return h('div')
69+
}
70+
)
71+
72+
const comp = <MyComp foo={'1'} bar={1} />
5273
```
5374

54-
</details>
5575

76+
## Using `useAttrs<T>` in `script-setup`
77+
78+
```vue
79+
<script setup lang="ts">
80+
const attrs = useAttrs<{bar: number}>()
81+
</script>
82+
```
5683

5784
## Using `defineCustomElement`
5885
```tsx
@@ -71,8 +98,12 @@ const Comp = defineCustomElement({
7198
# Motivation
7299
This proposal is mainly to infer `attrs` using `defineComponent`.
73100

74-
When using typescript in Vue3, the fallthrough attributes is unable to be used. It's not appropriate obviously that only one can be chosen from `typescript` and `the fallthrough attributes`. In most cases, we choose `typescript` and set attributes to `props` options instead of using the fallthrough attributes.
101+
When using typescript in Vue3, the fallthrough attributes is unable to be used. It's not appropriate obviously that only one can be chosen from `typescript` and `the fallthrough attributes`. In most cases, we choose `typescript` and set attributes to `props` option instead of using the fallthrough attributes.
75102

103+
Main scenes:
104+
105+
- Enhancing native html component, such as `button`, `input`...
106+
- Wrapping a component from UI library, such as `el-button` from [element-plus](https://github.com/element-plus/element-plus).
76107

77108
# Detailed design
78109

@@ -83,9 +114,10 @@ Due to typescript limitation from [microsoft/TypeScript#10571](https://github.co
83114
const Comp = defineComponent<Props, Attrs>({})
84115
```
85116

117+
86118
There still has two ways to be chosen.
87119

88-
1. Defining the first param that already existing, just like [vuejs/rfcs#192](https://github.com/vuejs/rfcs/pull/192) did.
120+
### 1. Defining the first param that already existing, just like [vuejs/rfcs#192](https://github.com/vuejs/rfcs/pull/192) did.
89121
```tsx
90122
const Comp = defineComponent({
91123
attrs: {} as { bar: number },
@@ -100,7 +132,7 @@ const Comp = defineComponent({
100132

101133
const comp = <Comp foo={'str'} bar={1} />
102134
```
103-
2. Defining the second param as proposed.
135+
### 2. Defining the second param as proposed.
104136
```tsx
105137
const Comp = defineComponent({
106138
props: {
@@ -115,17 +147,26 @@ const Comp = defineComponent({
115147
const comp = <Comp foo={'str'} bar={1} />
116148
```
117149

118-
At last i chosen the second way that pass `attrs` type to the second params of `defineComponent`, because I think the code of the component should not be involved just for type definition.
150+
At last I chosen the second way that passing `attrs` type to the second params of `defineComponent`, because I think the code of the component should not be involved just for type definition.
119151

120152

121153
The following below is the design details.
122154
- `attrs` is inferred to `{ class: unknown; style: unknown }` when the value of the second param is `undefined`
123155
- `attrs` is lower priority than `props`.
124-
- [see for more detail cases](https://github.com/vuejs/core/pull/7444/files)
156+
- [see for more detail cases](https://github.com/vuejs/core/pull/7444/files#diff-241bba82b0b4ebadd7a9c19ed82eed97283874b6d15ed32d62c05184e29ecb91R1195-R1306)
125157

126158
## `useAttrs<T>`
127159
In the `setup-script`, the generic type of `useAttrs` will compile to the second param of `defineComponent`.
128-
```ts
160+
161+
```vue
162+
<script setup lang="ts">
163+
const attrs = useAttrs<{bar: number}>()
164+
</script>
165+
```
166+
167+
Compiled Output:
168+
169+
```js
129170
export default /*#__PURE__*/_defineComponent({
130171
setup(__props, { expose }) {
131172
expose();

0 commit comments

Comments
 (0)