vue 版本3Props声明和使用

在 Vue 3 中,Props 声明有两种主要方式:Options API 中的 props 选项和 Composition API 中的 defineProps 宏。以下是它们的详细对比和使用说明:

一、核心区别

特性props (Options API)defineProps (Composition API)
使用场景Options API 组件<script setup> 组件
位置组件选项对象内<script setup> 顶层作用域
访问方式通过 this 访问通过返回值访问
响应性自动响应式自动响应式
TypeScript需 PropType 辅助原生支持类型推导
默认值default 属性default 属性 或 withDefaults
编译时运行时声明编译时宏(编译后消失)

二、props (Options API) 使用详解

export default {
  props: {
    // 类型声明
    title: String,
    
    // 详细配置
    count: {
      type: Number,
      required: true,
      validator: value => value >= 0
    },
    
    // 带默认值的对象
    config: {
      type: Object,
      default: () => ({ size: 'medium' })
    },
    
    // TS 类型支持
    book: {
      type: Object as PropType<Book>,
      default: null
    }
  },
  mounted() {
    console.log(this.title) // 通过 this 访问
  }
}

三、defineProps (Composition API) 使用详解

1. 基础用法
<script setup>
// 运行时声明 (JS)
const props = defineProps({
  title: String,
  count: {
    type: Number,
    required: true
  },
  tags: {
    type: Array,
    default: () => []
  }
})

console.log(props.title) // 直接访问
</script>
2. TypeScript 类型声明(推荐)
<script setup lang="ts">
// 纯类型声明 (TS)
interface Props {
  id: number
  title: string
  disabled?: boolean
  sizes?: string[]
}

const props = defineProps<Props>()
</script>
3. 带默认值的 TS 声明
<script setup lang="ts">
import { withDefaults } from 'vue'

interface Props {
  size?: 'sm' | 'md' | 'lg'
  labels?: string[]
}

// 提供默认值
const props = withDefaults(defineProps<Props>(), {
  size: 'md',
  labels: () => ['OK', 'Cancel']
})
</script>

四、关键差异详解

1. 类型系统支持
// Options API (需 PropType)
import type { PropType } from 'vue'

props: {
  book: {
    type: Object as PropType<Book>, // 需要类型断言
    required: true
  }
}

// Composition API (直接类型)
defineProps<{ book: Book }>()
2. 默认值处理
// Options API
props: {
  items: {
    type: Array,
    default: () => [] // 必须用工厂函数
  }
}

// Composition API (纯TS时)
withDefaults(defineProps<{ items?: string[] }>(), {
  items: () => ['default'] // 工厂函数
})
3. 访问方式
<script>
// Options API
export default {
  props: ['message'],
  methods: {
    show() {
      console.log(this.message) // 通过 this
    }
  }
}
</script>

<script setup>
// Composition API
const props = defineProps(['message'])
console.log(props.message) // 直接访问
</script>

五、最佳实践指南

  1. 新项目优先选择

    • 使用 <script setup> + defineProps + TypeScript

    • 获得更好的类型支持和更简洁的语法

  2. 默认值注意事项

    • 对象/数组必须使用工厂函数返回新实例

    // ✅ 正确
    default: () => [1, 2, 3]
    
    // ❌ 错误(共享引用)
    default: [1, 2, 3]
  3. 复杂验证

    defineProps({
      email: {
        validator(value) {
          return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value)
        }
      }
    })
  4. 跨API兼容

    • Options API 声明的 props 在 Composition API 的 setup() 中可通过参数访问

    export default {
      props: ['message'],
      setup(props) {
        console.log(props.message)
      }
    }

六、高级用法示例

1. 联合类型 + 默认值
<script setup lang="ts">
interface Props {
  variant?: 'primary' | 'secondary' | 'text'
}

const { variant = 'primary' } = defineProps<Props>()
</script>
2. 动态 Prop 名称
<script setup>
const dynamicKey = 'dynamicProp'

defineProps({
  [dynamicKey]: {
    type: String,
    default: ''
  }
})
</script>
3. 响应式解构(保留响应性)
<script setup>
import { toRefs } from 'vue'

const props = defineProps({ count: Number })
const { count } = toRefs(props) // 保持响应性
</script>

七、核心总结

特性props (Options)defineProps (Composition)
声明位置组件选项内<script setup> 顶层
类型支持需 PropType 辅助原生 TS 支持
默认值default 属性withDefaults 或 default
访问方式this.propNameprops.propName
响应性自动响应式自动响应式
编译处理运行时校验编译时宏(无运行时开销)
推荐场景传统 Options API 组件现代 Composition API 组件

迁移建议:新项目应优先使用 <script setup> + defineProps,老项目逐步迁移以获得更好的类型支持和开发体验。两者在功能上是等效的,但 Composition API 方式更符合现代 Vue 开发模式。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值