Vue series - Application of components in Vue

Hello, I'm Lanfeng, a program yuan from a second tier city. The first part is mainly shared with you< Vue series - Vue core application (II) Today, I will mainly share with you the answers related to vue's components, including component declaration, component types, several data communication methods between components and some common interview questions. I will specially sort out and share the answers related to vue's interview questions later.

Components in Vue are a very important part of development. The benefits of componentization are: easy maintenance, easy reuse and reducing unnecessary rendering

1, Declaration of components

1.1 global components

<my-button></my-button>  
Vue.component('my-button',{
  template:'<button>Order me</button>'
})
let vm = new Vue({
  el:'#app'
})

1.2 local components

<my-button></my-button>
let vm = new Vue({
  el:'#app',
  components:{
      'MyButton':{
          template:'<button>Button</button>'
      }
  }
});

HTML does not support self closing custom elements. Never use self closing components in DOM templates, nor in HTML MyButton is not supported So all component calls are connected by short horizontal lines!

2, Component data

The data in components must be in the form of functions to ensure that the data between each component is independent of each other

'MyButton':{
    data(){
        return {content:'Button'}
    },
    template:'<button>{{content}}</button>'
}

3, Component attribute application and verification

  • Attribute application
<my-button button-content="Button"></my-button>
components:{
    'MyButton':{
        props:['buttonContent'],
        template:'<button>{{buttonContent}}</button>'
    }
}

Attribute needs to use dash naming method on component label, and hump naming method is required for declaration in component

  • Attribute verification
<my-button button-content="Button" :number="'1'"></my-button>
components:{
    'MyButton':{
        props:{
            buttonContent:String,
            arr:{
                type:Array,
                default:()=>([])
            },
            number:{
                type:Number,
                validator:(value)=>{
                    return typeof value == 'number'
                }
            },

        },
        template:'<button>{{buttonContent}} {{arr}} {{number}}</button>'
    }
}

4, Communication between Vue components

Rapid prototyping: it can quickly identify. vue files, package components, plug-ins and other functions. It is also based on vue cli

sudo npm install @vue/cli -g
sudo npm install -g @vue/cli-service-global
vue serve App.vue

4.1 Props transfer data

components
   ├── Grandson1.vue // Grandson 1
   ├── Grandson2.vue // Grandson 2
   ├── Parent.vue   // father
   ├── Son1.vue     // Son 1
   └── Son2.vue     // Son 2

Use child components in parent components

<template>
 <div>
  Parent component:{{mny}}
  <Son1 :mny="mny"></Son1>
 </div>
</template>
<script>
import Son1 from "./Son1";
export default {
 components: {
  Son1
 },
 data() {
  return { mny: 100 };
 }
};
</script>

The child component accepts the properties of the parent component

<template>
 <div>Sub assembly 1: {{mny}}</div>
</template>
<script>
export default {
 props: {
  mny: {
   type: Number
  }
 }
};
</script>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
    <div id="app">
        <!-- The data of the parent component is passed in through the properties of the son -->
        {a:1,b:2,c:3}
        <my a=1 b=2 c=3></my>
    </div>
    <script src="node_modules/vue/dist/vue.js"></script>
    <script>
        // The one-way data flow parent component passes the data to the son
        //  Each component should have three parts: 1) HTML 2) JS 3) style
        let component = {
            template:`<div>Son {{mny}} <button @click="change">change</button></div>`,
            // props:['mny'], // this.mny = 100
            props:{ // Indicates that I want to verify the attribute
                mny:{
                    // For common types, you can write the default value directly. If it is an object or array, it must be written as the effect of the return value of the function
                    type:Object, // Type check
                    default:()=>({a:1})// Default value verification
                    // required:true / / required verification
                }
            },  
            methods:{
                change(){
                    this.mny = 200; // It's unreliable. The son should not change the father's data
                }
            },
            data(){
                return {m:1}
            },
            beforeCreate(){ // The parent-child relationship can be described here 
                console.log(this.$parent.$children[0] === this);
            },
        }
        // Vue.component('my',component)
        let vm = new Vue({
            el:'#app',
            beforeCreate(){
                console.log(this.$children);
                debugger;
            },
            data:{
                arr:[1,2,3],
                mny:'100'
            },
            components:{ // Register component on instance
                my:component
            }
        });
        // Three parts of component usage: 1) import a component 2) register 3) use in the template defined by the current component
    </script>
</body>
</html>

4.2 $emit usage

The child component triggers the parent component method to pass the modified content to the parent component through callback

<template>
 <div>
  Parent component:{{mny}}
  <Son1 :mny="mny" @input="change"></Son1>
 </div>
</template>
<script>
import Son1 from "./Son1";
export default {
 methods: {
  change(mny) {
   this.mny = mny;
  }
 },
 components: {
  Son1
 },
 data() {
  return { mny: 100 };
 }
};
</script>

Subcomponents trigger methods that bind to themselves

<template>
 <div>
  Sub assembly 1: {{mny}}
  <button @click="$emit('input',200)">change</button>
 </div>
</template>
<script>
export default {
 props: {
  mny: {
   type: Number
  }
 }
};
</script>

The main purpose here is to synchronize the data of parent and child components, and write the syntax sugar

.sync

<Son1 :mny.sync="mny"></Son1>
<!-- Event name triggered update:(binding.sync The name of the property) -->
<button @click="$emit('update:mny',200)">change</button>

v-model

<Son1 v-model="mny"></Son1>
<template>
 <div>
  Sub assembly 1: {{value}} // The triggered event can only be input
  <button @click="$emit('input',200)">change</button>
 </div>
</template>
<script>
export default {
 props: {
  value: { // The received property name can only be called value
   type: Number
  }
 }
};
</script>

4.3 [if the external chain image transfer fails, the source station may have an anti-theft chain mechanism. It is recommended to save the image and upload it directly (img-nkqx7b1c-1632833357131)( https://g.yuque.com/gr/latex?parent%E3%80%81#card=math&code=parent%E3%80%81&id=q8PMa )]children

Continue passing attributes

<Grandson1 :value="value"></Grandson1>
<template>
 <div>
  grandson:{{value}}
  <!-- Calling the parent component input event -->
  <button @click="$parent.$emit('input',200)">change</button>
 </div>
</template>
<script>
export default {
 props: {
  value: {
   type: Number
  }
 }
};
</script>

If the level is very deep, the transfer of [external chain pictures will fail. The source station may have an anti-theft chain mechanism. It is recommended to save the pictures and upload them directly (img-hr4jwcvt-163283357136)( https://g.yuque.com/gr/latex?parent.#card=math&code=parent.&id=BwfJD )]Parent... We can encapsulate a $dispatch method for upward distribution

$dispatch

Vue.prototype.$dispatch = function $dispatch(eventName, data) {
  let parent = this.$parent;
  while (parent) {
    parent.$emit(eventName, data);
    parent = parent.$parent;
  }
};

Since it can be distributed upward, it can also be distributed downward

$broadcast

Vue.prototype.$broadcast = function $broadcast(eventName, data) {
  const broadcast = function () {
    this.$children.forEach((child) => {
      child.$emit(eventName, data);
      if (child.$children) {
        $broadcast.call(child, eventName, data);
      }
    });
  };
  broadcast.call(this, eventName, data);
};

4.4 [the external chain picture transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the picture and upload it directly (img-bdufmbab-163283357138)( https://g.yuque.com/gr/latex?attrs%E3%80%81#card=math&code=attrs%E3%80%81&id=DV2lR )]listeners

$attrs

Batch drop in properties

<Son2 name="Little Everest" age="10"></Son2>

<!-- Can be in son2 Used in components $attrs attribute,You can continue to pass attributes down -->
<div>
  Son 2: {{$attrs.name}}
  <Grandson2 v-bind="$attrs"></Grandson2>
</div>


<template>
 <div>grandson:{{$attrs}}</div>
</template>

$listeners

Batch drop in method

<Son2 name="Little Everest" age="10" @click="()=>{this.mny = 500}"></Son2>
<!-- Can be in son2 Used in components listeners attribute,You can continue to pass the method down -->
<Grandson2 v-bind="$attrs" v-on="$listeners"></Grandson2>

<button @click="$listeners.click()">change</button>

4.5 Provide & Inject

Provide

Inject data into the parent

provide() {
  return { parentMsg: "father" };
},

Inject

Parent data can be injected into any child component

inject: ["parentMsg"] // The data will be mounted on the current instance

provide inject and context (you can declare a public data in the parent component). You can inject principles into the child components (it is confusing, and the name problem will not be used in the business code). The component library has multi-level communication. For convenience, you can use provide

4.6 Ref usage

Get component instance
ref gets the real dom element. If the component represents the instance of the current component, the parent component can directly get the methods or data of the child component

<Grandson2 v-bind="$attrs" v-on="$listeners" ref="grand2"></Grandson2>
mounted() { // Gets the properties of the component definition
  console.log(this.$refs.grand2.name);
}

4.7 EventBus

Used for cross component notification (this can be used for uncomplicated projects)

Vue.prototype.$bus = new Vue();

eventbus ( p a r e n t , parent, Parent (children) binding o n only can through too Bind set on can only be bound On can only be triggered by the component bound to on

The Son2 component and Grandson1 communicate with each other

 mounted() {
  this.$bus.$on("my", data => {
   console.log(data);
  });
 },
mounted() {
  this.$nextTick(() => {
   this.$bus.$emit("my", "I am Grandson1");
  });
 },

5, Interview questions

  • Communication mode between components

Tags: Javascript node.js Front-end npm Vue

Posted on Tue, 28 Sep 2021 15:25:26 -0400 by razmon