[Vue log] Eight ways to pass parameters of Vue components

Preface

The use of Vue components occurs frequently whether in ordinary work or in interviews. Therefore, it is necessary to systematically sort out the parameter transfer between components.

One, props transfer parameters

There are three ways to define props for subcomponents:

// 第一种数组方式
props: [xxx, xxx, xxx]
// 第二种对象方式
props: {
    
     xxx: Number, xxx: String}
// 第三种对象嵌套对象方式
props: {
    
    
    xxx: {
    
    
        //类型不匹配会警告
        type: Number,
        default: 0,
        required: true,
        // 返回值不是 true,会警告
        validator(val) {
    
     return val === 10}
    }
}

The third object supports 4 attributes by default, and all of them are not required. Can be used at will.

Two ways to pass parameters of the parent component

The first type of static property parameter transfer

note:

  1. When the props type is not defined, all props receive are String.
  2. When the props attribute is specified as Boolean, and only the attribute key has no value value, the received value is true.
<!--props 接受到的均为 String -->
<children xxx="123"></children>

<!-- 有只有属性没有值, 这种情况 props 指定类型是 Boolean 则接收到的是 true -->
<children xxx></children>

The second dynamic attribute parameter transfer

note:

  1. Need to distinguish the value passed in non-abbreviated form is an object, it will correspond to multiple values ​​in props
  2. Will preserve the type of the incoming value
  3. If it is an expression, what you get is the calculation result of the expression
<!-- 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>

Two, attrs and listeners

$attrs

$attrs will get the attributes that are not defined in props (except for the class and style attributes), which supports responsiveness. There are two commonly used scenarios:

  1. When components are nested, you can use $attrs to support excessive attribute support. For example, the table component of elementUI. There are more than a dozen attributes supported, and only one or two are used most often when encapsulating.
  2. The attribute is added to the parent component by default, and sometimes you want to add extra attributes to the child component (you can combine the inheritAttrs: false attribute to make the parent attribute not accept the extra attributes)

$listeners

The defined events are all on the root element of the child component, and sometimes you want to add it to other elements. You can use $listerners. It contains event listeners in the parent component (except for listeners with the .native modifier).

Three, $emit notification

By default, Vue has several methods: $on $emit $once $off to implement the publish and subscribe mode, which is also applied to component parameter transfer. The special method @abc=“methods” added to the component is equivalent to using $on to monitor this method. Therefore, the component can use $emit to notify.

Here is an exam question: How to get the value of the sub-component in the for loop and the value of the loop in the for
There are two answers, one is $event, and the other is closure. Just note that $event can only get the first value

<template v-for="item in [1, 2, 3]">
    <children @abc="((val, val2) => getValue(val, item))"></children>
</template>

Four, v-model

This is actually a combination of on. The advantage is that the synchronization value is convenient and the writing is elegant. The following three ways of writing actually have the same meaning

// 写法 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)}
    }
}

Five, slot

<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>

六、$refs, $root, $parent, $children

  1. $root Get the root component
  2. $parent gets the parent component
  3. $children Get child components (all child components, order is not guaranteed)
  4. $refs component gets component instance, element gets element

七、project / inject

Note: The injected value is non-responsive

<!--父组件 提供-->
{
    
    
    project() {
    
    
        return {
    
    
            parent: this
        }
    }
}
<!--子组件 注入-->
{
    
    
    // 写法一
    inject: ['parent']
    // 写法二
    inject: {
    
     parent: 'parent' }
    // 写法三
    inject: {
    
    
        parent: {
    
    
            from: 'parent',
            default: 222
        }
    }
}

Eight, Vuex

This is equivalent to a set of data maintained separately, so I won't say too much.

Guess you like

Origin blog.csdn.net/u013034585/article/details/106485621