The use of Vue components is a frequent occurrence both at work and in job interviews. Therefore, it is necessary to systematically comb through the parameters between components

A. Pass parameters for props

There are three ways for a subcomponent to define props:

// The first array method
props: [xxx, xxx, xxx]
// The second object mode
props: { xxx: Number.xxx: String}
// The third way to nest objects
props: {
    xxx: {
        // Type mismatch is warned
        type: Number.default: 0.required: true.// If the return value is not true, it will warn
        validator(val) { return val === 10}}}Copy the code

The third type of object supports four attributes by default, all of which are non-mandatory. Feel free to use

Two ways for the parent component to pass parameters

The first static attribute takes arguments

Note:

  1. If the props type is not defined, the props receives a String.
  2. True is accepted when the props attribute is set to Boolean and only the key attribute has no value value
<! --props props props props props props props
<children xxx="123"></children>

<! --> < div style = "border-box: none; border-box: none; border-box: none;
<children xxx></children>
Copy the code

The second dynamic attribute parameter is passed

Note:

  1. The value passed in the non-shorthand form is an object, which corresponds to multiple values in props
  2. The type of the passed value is preserved
  3. If it is an expression, the result of the expression is obtained
<! -- prop receives 123 of type Number -->
<children :xxx="123"></children>

<! -- Prop receives Array type [1, 2, 3]-->
<children v-bind:xxx="[1, 2, 3]." "></children>

<! Prop receives both xxx1 and xxx2 parameters. This abbreviation is not supported -->
<children v-bind="{xxx1: 1, xxx2: 2}"></children>
Copy the code

Second,listeners

$attrs

$attrs gets undefined properties (except the class and style properties) in props, which supports responsiveness. There are two common scenarios:

  1. Components nested components can use $attrs to support excessive attribute support. Consider the Table component of elementUI. More than a dozen attributes are supported, and the most commonly used when encapsulation is only one or two.
  2. Attributes are added to the parent component by default, and sometimes you want to add unnecessary attributes to the child component (you can use the inheritAttrs: False attribute to make the parent not accept unnecessary attributes).

Events defined by $Listeners are on the root element of the child component, and sometimes want to be added to other elements. You can use $listerners. It contains event listeners from the parent component (except listeners with the.native modifier)

$emit notification

By default, Vue provides $on $emit $once $off methods to implement the publish/subscribe mode. This is also applied to component arguments. The special @abc=”methods” method added to the component is equivalent to using $on to listen for this method. Therefore, $emit can be used within the component for notification.

Here’s a test question: how do I get the values of the child components and the values of the for loop

There are two answers, one is $event, and the other is closure. Just note that $event only gets the first value

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

Fourth, v – model

This is actually a kind of passThe combination of on. Advantages in synchronous value convenient, elegant writing. The following three ways actually mean the same thing

// 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'Update: + attribute name // 2. <children: a.sinc = = <children: a.sinc = ="a"></children>
{
    props: ['a']
    methods: {
        a() { this.$emit('update:a', 1)}}}Copy the code

Five, the slot

<template>
    <div>
        <! -- Default slot -->
        <slot></slot>
        <! -- another way to write the default slot -->
        <slot name="default"></slot>
        <! -- named slot -->
        <slot name="footer"></slot>
        <! -- Input slot -->
        <slot v-bind:user="user" name="header"></slot>
    </div>
</template>

<! - use - >
<children>
    <! -- Run to default slot -->
    <div>123</div>
    <! -- another way to write the default slot -->
    <template v-slot:default></template>
    <! -- Run to the named slot footer -->
    <template v-slot:footer></template>
    <! -- Abbreviated form -->
    <template #footer></template>
    <! Get the value of the child component -->
    <template v-slot:header="slot">{{slot.user}}</template>
    <! -- Structure slot value -->
    <template v-slot:header="{user: person}">{{person}}</template>
    <! -- Old style, can be written on a specific label -->
    <template slot="footer" slot-scope="scope"></template>
</children>
Copy the code

$refs, $root, $parent, $children

  1. $root gets the root component
  2. $parent gets the parent component
  3. $children get subcomponents (all subcomponents, order not guaranteed)
  4. The $refs component gets the component instance, and the element gets the element

7. Project/Inject

Note: Injected values are non-responsive

<! -- Parent component provides --> {project() {
        return{ parent: this } } } <! // Inject the core: ['parent'] // Inject: {parent:'parent'} inject: {parent: {from:'parent',
            default: 222
        }
    }
}
Copy the code

Eight, Vuex

This is equivalent to maintaining a separate set of data, but not much more.