Modern Vue Props Syntax
An overview of the updated props declaration syntax in Vue3, including the more flexible withDefaults and defineProps patterns.
Modern Vue Props Syntax
新项目,写组件传值,没太关注 Vue 版本更新,照着以前的习惯来:
1
2
3
4
5
6
7
8
<script setup lang="ts">
const props = defineProps({
title: {
type: String,
default: "",
},
});
</script>
不显式 assign props 也可以,但后面要用到值,还是写出来方便。用的时候 props.title 直接拿。
写着写着,想着既然是对象,直接解构不是更简洁:
1
2
3
4
5
6
<script setup lang="ts">
const { title } = props;
const handleClick = () => {
console.log(title);
};
</script>
然后发现不对劲——template 里用 title,父组件改了值,页面没反应。脑子转了一圈才反应过来:props 解构之后响应式丢了,title 只是解构那一刻的快照,之后父组件怎么改都跟它没关系了。
要用解构,得配 toRefs:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<script setup lang="ts">
import { toRefs } from "vue";
const props = defineProps({
title: {
type: String,
default: "",
},
});
const { title } = toRefs(props);
const handleClick = () => {
console.log(title.value); // 还得加 .value
};
</script>
每次解构都要 import toRefs,用的时候还要 .value。习惯了倒也还好,但总感觉在多走一步,有点 annoying。
Vue 3.5:直接解构,响应式不丢
Vue 3.5 把这个问题从根上解决了——defineProps 的返回值现在可以直接解构,响应式自动保留:
1
2
3
4
5
6
7
8
9
10
11
<script setup lang="ts">
const { title } = defineProps({
title: {
type: String,
},
});
const handleClick = () => {
console.log(title); // 不需要 .value
};
</script>
爱上了。
默认值也不用在 defineProps 里写 default 了,解构时直接赋:
1
2
3
4
5
6
7
<script setup lang="ts" name="my-card">
const { title = "你好" } = defineProps({
title: {
type: String,
},
});
</script>
如果是 TypeScript,还有更简洁的泛型写法,选项对象整个省掉:
1
2
3
<script setup lang="ts" name="my-card">
const { title = "你好" } = defineProps<{ title?: string }>();
</script>
title? 的 ? 表示 optional,默认值就在解构里给。类型和默认值一行搞定,很 TS。
纯 JS 项目没有泛型语法,还是要用对象形式,不过写法上影响不大:
1
2
3
4
5
<script setup lang="js" name="my-card">
const { title = "你好" } = defineProps({
title: String,
});
</script>
This post is licensed under CC BY 4.0 by the author.