【超细节】Vue3的属性传递——Props

目录

前言

一、定义

二、使用

1. 在 setup 中(推荐)

2. 非 setup 中

3. 对象写法的校验类型

4. 使用ts进行类型约束

5. 使用ts时props的默认值

三、注意事项

1. Prop 名字格式

2. 对象或数组类型的默认值

3. Boolean 类型转换


前言

Vue3相较于Vue2,Props传递的变化很大,并且结合ts后,写法有些怪异(choulou)。还有一些小细节,特此梳理一下。

一、定义

Vue3里组件之间属性传值需要显式声明它所接受的 props,这样 Vue 才能知道外部传入的哪些是 props,哪些是透传 attribute 。(关于透传attribute($attrs)在上文已讲,传送:Vue3中的透传Attributes / $attrs:简化组件开发的利器

在Vue2中,可以简单的用数组或者对象的写法写出来就行,如下:

// 写法一
export default {
  props: ['test'],
  created() {
    // props 会暴露到 `this` 上
    console.log(this.test)
  }
}

// 写法二
export default {
  props: {
    title: String,
    likes: Number
  }
}

但在Vue3中,就要区分是否使用 <script setup> 语法糖写法,还有是否使用ts。

二、使用

1. 在 setup 中(推荐)

注意:Vue3中只要是define开头的api,不需要从vue中引入。

<script setup>
// 数组写法
const props = defineProps(['test'])
console.log(props.tset)

// 对象写法并校验
defineProps({
  title: String,
  likes: Number
})
</script>

2. 非 setup 中

和Vue2保持一致

// 数组写法
export default {
  props: ['test'],
  setup(props) {
    // setup() 接收 props 作为第一个参数
    console.log(props.test)
  }
}

// 对象写法
export default {
  props: {
    title: String,
    likes: Number
  }
}

3. 对象写法的校验类型

 (来自Vue官网)

4. 使用ts进行类型约束

这个时候的写法可能就很不习惯了。

<script setup lang="ts">
defineProps<{
  title?: string
  likes?: number
}>()
</script>

拆分开来,其实等价于:

<script setup lang="ts">
interface Props {
  title?: string
  likes?: number
}

const props = defineProps<Props>()
</script>

5. 使用ts时props的默认值

当使用基于类型的声明时,我们失去了为 props 声明默认值的能力。

如果是对象写法,可以约定默认值,但是使用刚才第4点的ts进行类型约束后,就做不到了。这个时候可以通过 withDefaults 来解决:

export interface Props {
  msg?: string
  labels?: string[]
}

const props = withDefaults(defineProps<Props>(), {
  msg: 'hello',
  labels: () => ['one', 'two']
})

相当于是将整个之前的defineProps作为参数传给了withDefaults。

三、注意事项

1. Prop 名字格式

如果一个 prop 的名字很长,应使用 camelCase 形式,因为它们是合法的 JavaScript 标识符,可以直接在模板的表达式中使用.

<script>
    defineProps({
      greetingMessage: String
    })
</script>

<template>
    <span>{{ greetingMessage }}</span>
</template>

2. 对象或数组类型的默认值

当使用对象写法来进行对props进行约束时,对象或数组类型是最特殊的,它们的默认值必须从一个工厂函数 defult 返回:

defineProps({
  // 对象类型的默认值
  propAOrO: {
    type: Object,
    // 工厂函数写法
    default(rawProps) {
      return { message: 'hello' }
    }
  },

})

3. Boolean 类型转换

为了更贴近原生 boolean attributes 的行为,声明为 Boolean 类型的 props 有特别的类型转换规则。

这个规则就像原生的带Boolean 类型的html标签,例如input标签type为radio的单选框标签。其中如果属性添加上disabled,表示该单选框被禁用,无法进行选择。就等同于input里面对于disable属性默认为是true。

同理,当给组件声明为 Boolean 类型的 props ,也是这种规则。例如:

defineProps({
  ischecked: Boolean
})

那这个组件也可以直接这么使用:

<!-- 等同于传入 :ischecked="true" -->
<SonCom ischecked />

<!-- 等同于传入 :ischecked="false" -->
<SonCom />

  • 8
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
组件是 Vue.js 中最重要的概念之一。组件可以让我们将 UI 拆分为独立、可复用的部件,使得代码更加清晰、易于维护。在 Vue.js 中,组件可以分为全局组件和局部组件,其中全局组件可在任何地方使用,而局部组件只能在其父组件中使用。 定义组件时,需要使用 Vue.component() 方法,该方法需要传入两个参数:组件名称和组件配置对象。组件名称应该采用 kebab-case(短横线分隔命名)格式,以便在 HTML 中使用。 示例代码如下: ```javascript // 定义一个名为 button-counter 的新组件 Vue.component('button-counter', { data: function () { return { count: 0 } }, template: '<button v-on:click="count++">You clicked me {{ count }} times.</button>' }) ``` 在上述代码中,我们定义了一个名为 button-counter 的组件,该组件包含一个计数器,每次点击按钮计数器加一。 在 HTML 中使用组件时,需要使用组件名称作为自定义标签来调用组件。示例代码如下: ```html <div id="app"> <button-counter></button-counter> </div> ``` 在上述代码中,我们调用了 button-counter 组件,并将其渲染到了 id 为 app 的 div 元素中。 除了组件的 data 和 template 属性外,还可以使用 props 属性传递组件之间的数据。使用 props 时,需要在组件的配置对象中定义 props 属性,并在 HTML 中使用 v-bind 指令来传递数据。 示例代码如下: ```javascript // 定义一个名为 todo-item 的新组件 Vue.component('todo-item', { props: ['todo'], template: '<li>{{ todo.text }}</li>' }) // 创建一个 Vue 实例 var app = new Vue({ el: '#app', data: { groceryList: [ { id: 0, text: '蔬菜' }, { id: 1, text: '水果' }, { id: 2, text: '奶酪' } ] } }) ``` 在上述代码中,我们定义了一个名为 todo-item 的组件,并使用 props 属性定义了一个名为 todo 的 prop。在 HTML 中,我们使用 v-bind 指令将 groceryList 数组中的每个对象传递给了 todo-item 组件。示例代码如下: ```html <div id="app"> <ul> <todo-item v-for="item in groceryList" v-bind:todo="item" v-bind:key="item.id"></todo-item> </ul> </div> ``` 在上述代码中,我们使用 v-for 指令遍历 groceryList 数组,并使用 v-bind 指令将数组中的每个对象传递给了 todo-item 组件。注意,我们还需要使用 v-bind:key 指令来为每个列表项指定一个唯一的 key 值。 插槽是 Vue.js 中另一个重要的概念。插槽可以让父组件在子组件中插入任意的 HTML 内容,使得组件更加灵活、可复用。 在子组件中,使用 <slot> 标签来定义插槽。在父组件中,使用子组件的自定义标签来调用组件,并在标签内部插入 HTML 内容。示例代码如下: ```javascript // 定义一个名为 alert-box 的新组件 Vue.component('alert-box', { template: ` <div class="alert-box"> <strong>Error!</strong> <slot></slot> </div> ` }) // 创建一个 Vue 实例 var app = new Vue({ el: '#app' }) ``` 在上述代码中,我们定义了一个名为 alert-box 的组件,并在组件中定义了一个插槽。在 HTML 中,我们调用了 alert-box 组件,并在标签内部插入了一些 HTML 内容。示例代码如下: ```html <div id="app"> <alert-box> <p>Something bad happened.</p> </alert-box> </div> ``` 在上述代码中,我们调用了 alert-box 组件,并在标签内部插入了一些 HTML 内容。该 HTML 内容会被插入到 alert-box 组件的插槽中。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值