87
头图

Preface

After working on the company system for half a year, it was finally launched the day before yesterday. It took too long to fix the bug in the later period. Most of the bugs that appeared were caused by the asymmetry of the front-end and back-end information. There were not many logical errors. The user experience was slightly worse. After all, it was the first time to build such a large system (100w+ ), through the development of this system, I have summarized a lot of experience, how to better cooperate with the back-end personnel to develop and how to design to improve the user experience, the previous self-development did not pay attention to this aspect, only focused on the realization of the function. This piece is more supplementary.

After the project went online, the next step is the maintenance and update. Recently, the time has finally been not as busy as before, and I simply reviewed the system. Since the technology stack used in the project is Vue , the usual development only pays attention to the realization of functions. Next, we will Vue in depth to encapsulate common business components and Vue source code analysis.<br/><br/> This chapter will focus on Vue The 8 methods of component communication are summarized. The daily development of component communication is close, and familiarity with component communication can better develop business.

Vue transfer values between components

1. The parent component passes the value to the child component

    1. Introduce child components in parent components
    1. Register subcomponents
    1. Use in the page, dynamically bind the incoming dynamic value/static value on the sub-component label
    1. In the child component, use props to accept the value passed by the parent component

The value of the parent component received by the child component is divided into two types: reference type and ordinary type:

  • Common types: String, Number, Boolean, Null
  • Reference type: Array, Object
#父组件

<template>
  <div>
    <!-- 传递值 -->
    <Test
     :obj="obj" 
     info="测试"/>
  </div>
</template>

<script>
// 引入子组件
import Test from "../components/Test.vue";
export default {
  name: "about",
  // 注册子组件
  components: {
    Test,
  },
  data() {
    return {
      obj: {
        code: 200,
        title: "前端自学社区",
      },
    };
  },
};
</script>
<template>
    <div>
        <h1>{{obj.code}}</h1><br>
        <h2>{{obj.title}}</h2>
        <h3>{{info}}</h3>
    </div>
</template>

<script>
    export default {
        name:'test',
        props:{
            obj:Object,
            info: [String,Number]  //info值为其中一种类型即可,其他类型报警告
        }
    }
</script>
Since Vue is a one-way data flow, the child component cannot directly modify the value of the parent component.

2. The child component passes the value to the parent component

The child component passes through the binding event, through this.$emit('function name', passing parameters)
#父组件

<Test
     :obj="obj" 
     info="测试"
     @modify="modifyFatherValue"/>

<script>
// 引入子组件
import Test from "../components/Test.vue";
export default {
  name: "about",
  // 注册子组件
  components: {
    Test,
  },
  data() {
    return {
      msg:'我是父组件'
    };
  },
  methods:{
    // 接受子组件传递来的值,赋值给data中的属性
    modifyFatherValue(e){
      this.msg = e
    }
  }
};
</script>
# 子组件

<button @click="modifyValue">修改父组件的值</button>


<script>
    export default {
        name:'test',
        methods:{
            modifyValue(){
                this.$emit('modify','子组件传递过来的值')
            }
        }
    }
</script>

3. The parent component gets the child component value $refs / $children

$refs :

  • Obtain DOM elements and component instances to obtain component properties and methods.
  • By binding ref , use this.$refs.refName. subcomponent property/subcomponent method

$children :

  • The sub-components of the current instance, it returns a collection of sub-components. If you want to get which component properties and methods, you can pass this.$children[index]. child component properties/f method

Sample Text component

<script>
    export default {
        name:'test',
        data() {
            return {
                datas:"我是子组件值"
            }
        },
        props:{
            obj:Object,
            info: [String,Number]
        },
        methods:{
            getValue(){
                console.log('我是Test1')
            }
        }
    }
</script>

Example Text2 component

<template>
    <div>
        <h1>我是Test2</h1>
    </div>
</template>

<script>
    export default {
        name:'test',
        data() {
            return {
                datas:"我是Test2"
            }
        },
        created(){
         console.log( this.$parent.obj ) 
         this.$parent.getQuery()
        },
        methods:{
            getTest2(){
                console.log(this.datas)
            }
            
        }
    }
</script>

refs

<template>
  <div>
   // 给子组件上绑定 ref  
    <Test
      ref="son"
    />
   <Test2/>
  </div>
</template>

// 通过 $refs 示例来获取 子组件的属性和方法

 console.log( this.$refs.son.datas) 

 this.$refs.son.getValue()

$children

//  通过 $children  来获取 子组件的属性和方法
      this.$children[0].getValue(); // 我是 Test1
      this.$children[1].getTest2();  //我是 Test2
      console.log(`---------${this.$children[1].datas}`); //我是Test2

4. The child component obtains the properties and methods of the parent component instance $parent

<script>
    export default {
        name:'test',
        created(){
         console.log( this.$parent.obj ) 
         this.$parent.getQuery()
        },
        
    }
</script>

5. $attrs and $listeners get the properties and methods of the parent component instance (used in the case of component nesting)

$attrs : Contains feature bindings (except class and style) that are not considered (and not expected to be) props in the parent scope, and can be passed into internal components $attrs When a component does not declare any props , it contains all parent scope bindings (except class and style).

$listeners : Contains the v-on event listener in the parent scope (without the .native modifier). It can be passed to internal components via v-on=" $listeners It is an object that contains all event listeners acting on this component, which is equivalent to the child component inheriting the event of the parent component.

Use scenario: Use in the case of multi-layer nested components, you can avoid using Vuex for data processing, using v-bind="$attrs" v-on="$listeners" is very convenient to achieve business data transfer.

Parent component

<template>
    <div>
        <Test3  
        :status="status" 
        :title="title"
        @getData="getData" />
    </div>
</template>

<script>
import Test3 from "../components/Test3.vue";
    export default {
        name:'person',
        data(){
            return {
                title:'personal 组件',
                status: false
            }
        },
        methods:{
          getData(){
              console.log(this.title)
          }  
        },
        components:{
            Test3
        }
    }
</script>

Subcomponent 1

<template>
  <div>
    <h1>Test3 组件</h1>
    <br /><br />
    // 通过 $attrs(属性,除了【props中定义的属性】)  和 $listeners(方法)  来给嵌套子组件传递父组件的属性和方法
    <Test4   v-bind="$attrs" v-on="$listeners"/>
  </div>
</template>

<script>
// 引入子子组件   
import Test4 from "../components/Test4";
export default {
  name: "test3",
  props: ["title"],
  components: {
    Test4,
  },
  created() {
    console.log(this.$attrs);  //{status: false}
    console.log("-----------");
    console.log(this.$listeners); // {getData: ƒ}
  },
};
</script>

Nested subcomponents

<template>
    <div>
        <h1>Test4 组件</h1>
    </div>
</template>

<script>
    export default {
        name:'test4',
        created(){
            console.log('-----Test4------')
            console.log(this.$attrs) //{status: false}
            console.log(this.$listeners) // {getData: ƒ}
        }
    }
</script>

6. Passing values between components

By js new 060fa0690e4687 file, importing vue , exporting vue instance; then by binding the event $emit event to the exported instance, and then $on , so that global component data sharing can be achieved.

scenes to be used:

It can transfer data in any scenario, parent-child components pass values, son-parent pass values, brother components pass values, cross-level components pass values.

This solution can be used when the communication data is relatively simple, and the project is relatively large, so Vuex can be used.

vue .js

/*
 * @Description: 
 * @Author: ZhangXin
 * @Date: 2021-01-22 15:48:56
 * @LastEditTime: 2021-01-22 15:51:24
 * @LastEditors: ZhangXin
 */

 import Vue from 'vue'

 export default new Vue()

Component A

<!--
 * @Description: 
 * @Author: ZhangXin
 * @Date: 2021-01-22 14:44:17
 * @LastEditTime: 2021-01-22 16:25:33
 * @LastEditors: ZhangXin
-->

<template>
    <div>  
        <button @click="changeValue">改变</button>
    </div>
</template>

<script>
import zxVue from '../util/newVue.js';
    export default {
        name:'person',
        data(){
            return {
                title:'personal 组件',
                status: false
            }
        },
        methods:{
          changeValue(){
             // 通过给 vue实例绑定事件
             zxVue.$emit("getTitle", this.title)   
          }  
        }
    }
</script>


Component C

<!--
 * @Description: 
 * @Author: ZhangXin
 * @Date: 2021-01-22 15:07:30
 * @LastEditTime: 2021-01-22 16:26:38
 * @LastEditors: ZhangXin
-->
<template>
  <div>
    <h1>Test4 组件</h1>
    <h1>{{ title }}</h1>
  </div>
</template>

<script>
import zxVue from "../util/newVue";
export default {
  name: "test4",
  data() {
    return {
      title: "test4",
    };
  },
  mounted(){
    // 通过 vue 实例.$on  监听事件名,来接收跨级组件传递过来的值
    zxVue.$on("getTitle", (item) => {
      this.title = item;
      console.log(item)
    });

  }
};
</script>

7. Vuex

I won’t introduce it here, I will write an article separately after Vuex

8. provide and inject realize the parent component to pass values to the descendants. (Unlimited level)

provide and inject need to be used together to allow an ancestor component to inject a dependency into all its descendants, no matter how deep the component level is, and it will always take effect when the upstream and downstream relationship is established.

provide :

  • Is an object or a function that returns an object
  • This object contains properties that can be injected into its descendants.

inject :

  • Is an array of strings or an object
  • Used to inject parent component attributes provided by provide into child components or descendant components.

scenes to be used:

provide/inject can easily achieve cross-level access to the data of the parent component

# provide
//对象
provide:{
    name:'测试'
}
//返回对象的函数
provide(){
    return {
        name: '测试'
    }
}

#inject
inject:['name']

Parent component

<!--
 * @Description: 
 * @Author: ZhangXin
 * @Date: 2021-01-22 23:24:16
 * @LastEditTime: 2021-01-22 23:49:50
 * @LastEditors: ZhangXin
-->
<template>
    <div>
        <h1>我是父组件</h1>
        <Son />
    </div>
</template>

<script>
import Son from '../components/son/SonOne'
    export default {
        name:'father',
        provide(){
            return {
                titleFather: '父组件的值'
            }
        },
        components:{
            Son
        },
        data(){
            return{
                title:'我是父组件 '
            }
        },
        
    }
</script>

Subassembly

<template>
    <div>
        <h1>我是子孙组件</h1>
       
    </div>
</template>

<script>
import SonTwo from '../son/SonTwo'
    export default {
        name:'sonone',
        components:{
           SonTwo
        },
        inject:['titleFather'],
        created(){
             console.log(`${this.titleFather}-----------SonTwo`)
        },
        data(){
            return{
                title:'我是子组件 '
            }
        },
        
    }
</script>

Descendant components

<template>
    <div>
        <h1>我是子孙组件</h1>
       
    </div>
</template>

<script>
import SonTwo from '../son/SonTwo'
    export default {
        name:'sonone',
        components:{
           SonTwo
        },
        inject:['titleFather'],
        created(){
             console.log(`${this.titleFather}-----------SonTwo`)
        },
        data(){
            return{
                title:'我是子组件 '
            }
        },
        
    }
</script>

Concluding remarks

❤️Follow+Like+Favorite+Comment+Repost❤️, originality is not easy, I encourage the author to create better articles


程序员海军
942 声望7k 粉丝