Vue 组件的使用无论是在日常工做仍是在面试面试中,都是频繁出现的。所以系统的梳理一下组件之间的传参仍是很是有必要的html
// 第一种数组方式
props: [xxx, xxx, xxx]
// 第二种对象方式
props: { xxx: Number, xxx: String}
// 第三种对象嵌套对象方式
props: {
xxx: {
//类型不匹配会警告
type: Number,
default: 0,
required: true,
// 返回值不是 true,会警告
validator(val) { return val === 10}
}
}
复制代码
第三种对象默认支持 4 种属性,而且都是非必填的。能够随意使用面试
第一种静态属性传参数组
注意:bash
<!--props 接受到的均为 String -->
<children xxx="123"></children>
<!-- 有只有属性没有值, 这种状况 props 指定类型是 Boolean 则接收到的是 true -->
<children xxx></children>
复制代码
第二种动态属性传参闭包
注意:ui
<!-- prop 接收到 Number 类型的 123-->
<children :xxx="123"></children>
<!-- prop 接收到 Array 类型的 [1, 2, 3]-->
<children v-bind:xxx="[1, 2, 3]"></children>
<!-- prop 会接收到 xxx1 和 xxx2 俩个参数。这种不支持简写形式-->
<children v-bind="{xxx1: 1, xxx2: 2}"></children>
复制代码
$attrsthis
$attrs 会获取到 props 中未定义的属性(class 和 style 属性除外),支持响应式。经常使用的场景有俩种:spa
$listeners 定义的事件都在子组件的根元素上,有时候想加到其余元素上。就可使用 $listerners。它包含了父组件中的事件监听器(除了带有 .native 修饰符的监听器)code
Vue 默认有 $on $emit $once $off 几种方法来实现发布订阅模式,这也应用在了组件传参上。在组件上添加的特殊方法 @abc="methods" 就至关于使用了 $on 来监听这个方法。所以组件内可使用 $emit 来进行通知。htm
这里有一道考题: for 循环的时候如何拿到子组件的传值和 for 中循环的值
答案有俩种,一是 $event, 二是 闭包。只是须要注意 $event 只能获取到第一个值
<template v-for="item in [1, 2, 3]">
<children @abc="((val, val2) => getValue(val, item))"></children>
</template>
复制代码
这个实际上是一种经过 on 的组合方式。优势再于同步值方便,写法优雅。下面三种写法实际上是一个意思
// 写法 1
<children v-model="a"></children>
{
model: {
prop: 'value',
event: 'update:a',
},
methods: {
a() { this.$emit('update:a', 1)}
}
}
// 写法 2
<children :a="a" @update:a="a = $event"></children>
{
props: ['a']
methods: {
a() { this.$emit('update:a', 1)}
}
}
// 写法 3
// 1. 事件名必须是 update: + 属性名
// 2. 参数不能是表达式,最好是 data 里面的属性
<children :a.sync="a"></children>
{
props: ['a']
methods: {
a() { this.$emit('update:a', 1)}
}
}
复制代码
<template>
<div>
<!--默认插槽-->
<slot></slot>
<!--另外一种默认插槽的写法-->
<slot name="default"></slot>
<!--具名插槽-->
<slot name="footer"></slot>
<!--传参插槽-->
<slot v-bind:user="user" name="header"></slot>
</div>
</template>
<!--使用-->
<children>
<!--跑到默认插槽中去-->
<div>123</div>
<!--另外一种默认插槽的写法-->
<template v-slot:default></template>
<!--跑到具名插槽 footer 中去-->
<template v-slot:footer></template>
<!--缩写形式-->
<template #footer></template>
<!--获取子组件的值-->
<template v-slot:header="slot">{{slot.user}}</template>
<!--结构插槽值-->
<template v-slot:header="{user: person}">{{person}}</template>
<!--老式写法,能够写到具体的标签上面-->
<template slot="footer" slot-scope="scope"></template>
</children>
复制代码
注意:注入的值是非响应的
<!--父组件 提供-->
{
project() {
return {
parent: this
}
}
}
<!--子组件 注入-->
{
// 写法一
inject: ['parent']
// 写法二
inject: { parent: 'parent' }
// 写法三
inject: {
parent: {
from: 'parent',
default: 222
}
}
}
复制代码
这个至关于单独维护的一组数据,就不过多的说了。