如何在 vue3 的 <脚本设置>中使用 props



就像标题所说的,相关链接:新script setup(不含ref糖)

<template>
<TopNavbar title="room" />
<div>
{{ no }}
</div>
</template>
<script setup>
import TopNavbar from '@/layout/TopNavbar.vue'
import { defineProps, reactive } from 'vue'
defineProps({
no: String
})
const state = reactive({
room: {}
})
const init = async () => {
// I want use props in this
// const { data } = await getRoomByNo(props.no)
// console.log(data);
}
init()
</script>
<style>
</style>

要使用<script setup>的道具,你需要调用defineProps()的组件道具选项作为参数,这定义了组件实例上的道具,并返回一个reactive对象与道具,你可以使用如下:

<template>
<TopNavbar title="room" />
<div>
{{ no }}
</div>
</template>
<script setup>
import TopNavbar from "@/layout/TopNavbar.vue";
import { defineProps, reactive } from "vue";
const props = defineProps({
no: String,
});
const { no } = toRefs(props);
const state = reactive({
room: {},
});
const init = async () => {
const { data } = await getRoomByNo(no.value);
console.log(data);
};
init();
</script>

如果你正在使用typescript,另一种方法是传递一个仅类型声明,并从中推断prop类型。优点是你会得到更严格的类型安全,但是你不能有默认值

<template>
<TopNavbar title="room" />
<div>
{{ no }}
</div>
</template>
<script setup>
import TopNavbar from "@/layout/TopNavbar.vue";
import { defineProps, reactive } from "vue";
const props = defineProps<{
no: string,
}>();
const { no } = toRefs(props);
const state = reactive({
room: {},
});
const init = async () => {
const { data } = await getRoomByNo(no.value);
console.log(data);
};
init();
</script>

编辑

默认的只有类型的道具现在是可能的:

interface Props {
msg?: string
}
const props = withDefaults(defineProps<Props>(), {
msg: 'hello'
})

非常简单的答案,使用Vue-3.1和更高版本的功能:

CircleImage.vue

<template>
<div class="px-4 w-8/12 sm:w-3/12">
<img :src="src" :alt="alt" class="border-none rounded-full h-auto max-w-full align-middle" />
</div>
</template>
<script setup>
const props = defineProps({
src: String,
alt: String,
})
</script>

MyView.vue

<template>
<div class="flex flex-wrap justify-center">
<CircleImage src="/file1.jpg" alt="one" />
<CircleImage src="/file2.svg" alt="two" />
</div>
</template>
<script setup>
import CircleImage from '@/components/CircleImage.vue'
</script>

另见文档:声明道具或附加选项

我读了"Newscript setup"找到了答案

首先,使用变量savedefineProps
const props = defineProps({
no: String
})

然后使用

const init = async () => {
console.log(props.no);
}

这是所有代码:

<template>
<TopNavbar title="room" />
<div>
{{ no }}
</div>
</template>
<script setup>
import TopNavbar from '@/layout/TopNavbar.vue'
import { defineProps, reactive, useContext } from 'vue'
const props = defineProps({
no: String
})
const state = reactive({
room: {}
})
const init = async () => {
console.log(props.no);
}
init()
</script>
<style>
</style>

无需显式调用withDefaults

<script setup>
import { defineProps } from 'vue'
defineProps({
isOpen: {
type: Boolean,
default: true
}
})
</script>

编辑:这个答案已经过时了。RFC更改为使用defineProps(..),如果使用sfc则会自动导入。

根据正在进行的RFC,setup标签可以有一个字符串,您可以在其中定义您希望拥有的上下文,如下所示:

<script setup="props, { emit }">
import { watchEffect } from 'vue';
watchEffect(() => console.log(props.msg));
emit('foo');
</script>

这些参数与setup()方法接收的参数相同。

如果你想让你的props是响应式的,你可以在你的子组件中这样设置它们:

const props = defineProps({
no: String,
myIdOfSomething: Number
})
const { no, myIdOfSomething } = toRefs(props);
console.log(no.value)
console.log(myIdOfSomething.value)

源https://vuejs.org/api/sfc-script-setup.html defineprops-defineemits

UsingTypescript你可以用两种语法定义你的props:

  1. 第一次语法

<script setup lang="ts">
import {PropType} from 'vue'
const props=defineProps({
color:{
type:String as PropType<'primary'|'info'|'success'|'error'|'warning'>,
default :'primary'
}
})
</script>
  1. 第二种语法

<script setup lang="ts">
type Color='primary'|'info'|'success'|'error'|'warning'
const props=defineProps<{color:Color}>()
</script>

此语法只支持:

  • 类型文字
  • 对同一文件中接口或类型文字的引用

如果您正在使用Typescript,并且还想添加默认值,您可以使用此语法。

<script setup lang="ts">
interface Props {
disabled?: boolean;
loading?: boolean;
bordered?: boolean;
label: string;
}
const props = withDefaults(defineProps<Props>(), {
label: "Button Label",
}); 
</script>

最新更新