vue props 写法更新

props 的写法更加灵活

Posted by My on October 7, 2024

前言

这个项目是新起的,另外也没有注意 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>