Post

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>

其实可以不显示的定义 props,但是考虑后面操作要使用到 props 的值,就显示定义 props 了。

那这就是我以前的习惯,默认值通过 default 定义,而后续使用到 props 的值时,就这样使用:

1
2
3
4
5
6
7
8
9
10
11
<script setup lang="ts">
const props = defineProps({
  title: {
    type: String,
    default: "",
  },
});
const handleClick = () => {
  console.log(props.title);
};
</script>

而对于 props 里的值,可以使用解构(我觉得不太方便),就像这样:

1
2
3
4
5
6
<script setup lang="ts">
const { title } = props; // 解构
const handleClick = () => {
  console.log(title);
};
</script>

但是这样解构方式是不合理的,也是不生效的。这样解构出来的 title 不具有响应式特性,而且在 template 中也不生效。因此,需要解构时,必须配合 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); // 解构出来的 title 具有响应式特性
};
</script>

vue3.5 版本的写法

摒弃了辅助函数 toRefs,也不再需要通过 default 来定义默认值。

解构写法

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>

这种写法更加简洁了,不需要使用 toRefs 辅助函数,爱上了!

props 默认值

可以在解构的时候直接赋值。

1
2
3
4
5
6
7
8
9
10
11
12
<script setup lang="ts" name="my-card">
// 这里的 title 就是默认值
const { title = "你好" } = defineProps({
  title: {
    type: String,
  },
});

const handleClick = () => {
  console.log(title);
};
</script>

一般写法

这样在 defineProps 里使用对象定义 title 的类型还是很明确的,但有些不太符合 ts 的风格,所以针对 ts,一般可以这样写:

1
2
3
4
5
6
7
<script setup lang="ts" name="my-card">
const { title = "你好" } = defineProps<{ title?: string }>();

const handleClick = () => {
  console.log(title);
};
</script>

但是,如果是 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.