笔记源于:慕课网 vue3+ts打造企业级组件库

github:https://github.com/Ulrica-CH/v3-comp

npm i -g @vue/cli

vue create demo(v3 ts jest eslint+prettier)

定义组件及props类型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<template>
<div class="hello">Hello</div>
</template>

<script lang="ts">
import { PropType, defineComponent } from "vue";
interface IConfig {
name: string;
}
export default defineComponent({
name: "HelloWorld",
props: {
msg: String,
config: {
type: Object as PropType<IConfig>,
},
},
mounted() {
/** 类型提示 及限制 */
this.config?.name;
},
});
</script>

默认的type:Object是js 要是有propType转为ts支持的,这样转换后会有更好的类型提示以及校验

required:true坑点

1
2
3
4
5
6
7
8
9
10
props: {
msg: String,
config: {
type: Object as PropType<IConfig>,
},
age: {
type: String,
required: true,
},
},

默认这样是可以的,使用组件不传递age会报错

但如果把props提取出来

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<script lang="ts">
import { PropType, defineComponent } from "vue";
interface IConfig {
name: string;
}
const IProps = {
msg: String,
config: {
type: Object as PropType<IConfig>,
},
age: {
type: String,
required: true,
},
};
export default defineComponent({
name: "HelloWorld",
props: IProps,
mounted() {
/** 类型提示 及限制 */
this.config?.name;
},
});
</script>

这样是不会报错的,因为默认的吧required: true,当成readOnly了

要as const

1
2
3
4
5
6
7
8
9
10
const IProps = {
msg: String,
config: {
type: Object as PropType<IConfig>,
},
age: {
type: String,
required: true,
},
} as const;

这样就正常了

h函数

1
2
3
4
5
6
const App1 = defineComponent({
render() {
return h("div", { id: "app" }, [h("h2", ["9999"])]);
},
});
createApp(App1).mount("#app");

setup render

1
2
3
4
5
6
7
8
9
10
11
12
const App1 = defineComponent({
setup() {
const nameRef = ref("sss");

setInterval(() => {
nameRef.value += 1;
}, 2000);
return () => {
/** setup初始化只会执行一次,放到return上面不会更新 */
const number = nameRef.value;
return h("div", number);
};

vue3 JSX

pnpm add @vue/babel-plugin-jsx

babel.config.js

1
2
3
4
5
6
module.exports = {
presets: ["@vue/cli-plugin-babel/preset"],
/** add */
plugins: ["@vue/babel-plugin-jsx"],
};

App.tsx

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import { defineComponent, ref } from "vue";
import HelloWorldVue from "./HelloWorld.vue";
const App = defineComponent({
setup() {
const nameRef = ref("sss");

setInterval(() => {
nameRef.value += 1;
}, 2000);

return () => {
return (
<div>
{nameRef.value}
<HelloWorldVue age={"12"} />
<input v-model={nameRef.value} />
</div>
);
};
},
});
export default App;

说实话 很灵活…