[Vue] Several methods of passing values in Vue, case code analysis

Table of contents

1. Reverse value transfer (child component passes value to parent component)

2.$refs

3.$parent

4.$children

5.$attrs/$listeners -----Multi-layer value transfer

6. $root ---- root component

7. Dependency injection provide/inject

8.v-model

9. Central event bus


1. Reverse value transfer (child component passes value to parent component)

        We often encounter modal windows as shown in the picture in web pages. The effect we want to achieve is that when we click the close button on the upper right, the modal window disappears. In Vue, we want to hide an element from the page. You can use v-if or v-show to change the value from true (shown) to false (hidden).

        ​ ​ Then our idea is to click the close button and set the value of the flag. The code is explained as follows

         Bind the click event to the close button, @click="clear" The event here is bound to the child component, and the effect we want to achieve is to change the data in the parent component (data-driven page, display of the modal window in the page and hidden are determined by the data flag),

First, we use attribute value transfer to pass flag: true to the sub-component.

 

 Please note, this involves knowledge point single data flow. Data can only flow from the parent component to the child primary key. Modifying the attribute value will only refresh the child component. The parent The component's data is not updated. Explain that the parent component data is passed to the child component (property value transfer), and the child component is passed to the parent component (inversely Pass value)

We want to solve this problem and want to change the value in the parent component as follows (reverse value transfer):

Because the data flow is one-way: the child component triggers the event this.$emit("event name", data 1, data 2, ````), and the parent component binds the event @event name = "listener" ;

1. Bind an event on the parent component. What is the purpose of this event that is unofficially designed by yourself?

2. Trigger a custom event in the child component this.$emit ("The first parameter is the name of the triggered event", "The second parameter is the data passed to the parent component")

3. Pass the value of the child component to the parent component and change the data in the parent component (reverse value transfer)

The code is analyzed as follows:

Parent component code:

Subcomponent code:

 The code has also been sent out, so you can implement it:

Parent component:

<template>
  <div>
    <img class="img" src="https://img0.baidu.com/it/u=3443901670,2726678779&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=281"
      alt="">
    <span>父组件中flag的值---{
   
   { flag }}</span>
    <Motail v-if="flag" :a1="flag" @updata="fn"></Motail>
  </div>

</template>

<script>
import Motail from "@/motai/Motail.vue"
export default {
  components: {
    Motail,
  },

  data() {
    return {
      flag: true
    }
  },

  methods: {
    fn(arg) {
      // 事件传进来的参数值为事件触发子组件传给父组件的值
      console.log(arg, "1111111111111");
      this.flag = arg;
    }
  }
}
</script>

<style>
.img {
  width: 100%;
  height: 100%;
}
</style>

 Subassembly:

<template>
    <div class="Motail">
        <div class="box">
            <div>
                <span>这是弹出的模态窗</span><br>
                <span>打印父组件传过来的a1值---{
   
   { a1 }}</span>
            </div>
            <div class="x" @click="clear1">&times;</div>
        </div>
    </div>
</template>

<script>
export default {
    props:["a1"],
    methods:{
        clear1(){
            // 给关闭按钮绑定点击事件
            // 想办法把父组件中的数据源修改了 
            // 数据驱动页面,页面中模态窗口的显示和隐藏由数据决定的(flag:true)
            console.log(this.a1);//打印父组件的传过来的flag的值
            //this.a1="false";
            // 触发自定义事件  
            // 第一个参数update为触发事件的名字
            // 第二个参数为传给事件的数据(子组件传给父组件)
            this.$emit("updata",false)

            
        }
    }
}
</script>


<style>
.Motail {
    width: 100vw;
    height: 100vh;
    background-color: rgba(112, 112, 112, 0.5);
    position: fixed;
    z-index: 20;
    top: 0px;
    right: 0px;
    display: flex;
    justify-content: center;
    align-items: center;
}

.box {
    width: 300px;
    height: 200px;
    font-weight: 30px;
    font-weight: 800;
    background-color: white;
    position: relative;
    border-radius: 10px;
    line-height: 100px;
    text-align: center;

}

.x {
    height: 30px;
    width: 30px;
    background-color: rgb(116, 119, 121);
    border-radius: 50%;
    color: white;
    font-weight: 800;
    font-size: 30px;
    text-align: center;
    line-height: 30px;
    position: absolute;
    top: 0px;
    right: 0px;

}
</style>

2.$refs

In vue, it is not recommended that we do DOM operations, but it provides methods for DOM operations.

The DOM operation interface provided by vue, bind ref="mark" on the element or component, and obtain the this.$refs. tag in the component.

 ​​

 If we want to get a specific element, use the direct object to get the value method, for example: this.$refs.p1 gets the tag with ref="p1".

 In addition to getting elements on the page, ref can also get components

For example:

 

 Here VueComponent represents the constructor of the reference data, which is a class in the vue framework, and the component object is created by VueCompoent.

3.$parent

Summary: The parent component of the current component. The parent component can also be called in a chain to obtain the parent component. The root component has no parent component.

As mentioned in the blog of this chapter, it is troublesome to modify the data of the parent component when the child component transmits data to the parent component. Here we introduce $parent, which can directly modify the data of the parent component, eliminating the need for binding events, triggering events and other steps.

This in this.$parent represents the current component, and .$parent represents the parent component of the current component. You can directly change the flag value in the data in the parent component using this.$parent.flag.

 Extension:App’s parent component is Vue, which means that the root component is Vue, and the constructor of the root component is not VueCompoent, but Vue. The parent component of the root component is undefined

4.$children

Summary: It is an array. The array contains the sub-components of the current component. It does not include sub-elements and the order is not guaranteed.

Same as the third one, you can use $children to access child components. A child component has only one parent component, and a parent component can have many child components. To put it simply, a son can only have one father, but a father can have many sons.

Since we are talking about a parent component having more than one child component, what is returned is not an object but an array.

 $children also has many disadvantages. For example, if we get the first subcomponent in this.$children[0], if we change the first subcomponent v-if="false" to v- for="true", the component is not necessarily the first (it is added to the end of the current component according to time, related to the time of addition), the order obtained here is related to the code we write The order does not matter. Therefore, we do not recommend using $children to obtain child components

5.$attrs/$listeners -----Multi-layer value transfer

It is very cumbersome to use the reverse value transfer method to pass values ​​in several parent-child relationships. In order to solve this problem, there are multiple layers of value transfer (transition function).

attrs is the abbreviation of the English word attribute sttributes, which means that all the attributes passed by the parent component of the component will not be used in this component, but will be passed directly to the next-level component (the picture indicates that it is passed to the Box2 component), and then passed to Box2 , and then use props:[""] to receive.

If you want to modify the data in the parent component, use a trigger event (that is, this.$emit("event name", data 1, data 2, ````)). You also need to add v here. -on="$listeners" serves as a delivery function and the delivery of listeners.

example:

App------>Box1-------->Box2

App code:

<template>
  <div>
    <p>app-----{
   
   { msg }}</p>
    <Box1  :a1="msg" @change="fn"></Box1>
  </div>

</template>

<script>
import Box1 from "@/Box/Box1.vue"
export default {
  data(){
    return {
      msg:"app组件的数据"
    }
  },
  methods:{
    fn(arg){
      console.log(arg,1111111111);//arg表示box2传回来的数据
      this.msg=arg;
    }
  },
  components:{
    Box1,
  }
}

</script>

<style>
</style>

 The code of App’s sub-component Box1:

<template>
    <div>
       <Box2 v-bind="$attrs" v-on="$listeners"></Box2>
    </div>
</template>

<script>
import Box2 from "@/Box/Box2.vue"
export default {
  data(){
    return {
      msg:"app组件的数据"
    }
  },
  components:{
    Box2,
  }
}

</script>

<style>
</style>

 The code of sub-component Box2 of App’s sub-component Box1:

<template>
    <div>
        <p>box2----{
   
   { a1 }}</p>
        <button @click="fn1">box2-btn</button>
    </div>
</template>
<script>
export default {
    props: ["a1"],
    methods:{
        fn1(){
            console.log(this.a1);
            this.$emit("change","这是box2传给App的数据")
        }
    }
}
</script>
<style>

</style>

6. $root ---- root component

        This.$root can get the root component. There is only one root component in each vue framework. We can put data into the root component to avoid the tedious value transfer between child and parent components.

In subsequent uses, we can use $root to pass values ​​to sibling components.

7. Dependency injection provide/inject

Dependency injection is more concise than multi-layer value passing. Multi-layer value passing intermediate components need to write code v-bind="$attrs" v-on="$listeners" for transition. The disadvantage of dependency injection is that the data provided by the provider cannot be modified. All components can become providers of provide, and inject is the descendant of the provider

provideprovide data 

<script>
export default {
  provide(){
    return{
      msg2:"app组件提供的数据"
    }
  }
}

</script>

inject receives data

<script>
    export default{
        inject:["msg2"]
    }
</script>

8.v-model

In the previous learning stage, we knew that v-model is syntactic sugar, and the same can be used here.

In one, we will change :a1 to:value,  @updata changed to @input,  

It can be rewritten into the following format 

<Box v-model="flag"></Box>

v-model can save the following step, which is to get the value passed by the event trigger to change the value of the current component.

The bottom layer of v-model="flag" is the synthesis of two grammars

1. Attribute binding: value="flag"

2. Is @input bound or the received data is set to this.flag in the function?

 v-model is a special case of the following (the event binding step is omitted)

9. Central event bus

It is mentioned in $root that operations can be performed on the root component vue, but various bindings on vue that renders web pages will affect performance.

Solution: Create a new vue and perform various bindings on the newly created vue. By creating a new vm object, events are registered uniformly for all components to operate together, achieving the effect of all components passing values ​​from generation to generation at will.

Usage example:

this.$bus.emit

 this.$bus.on

Guess you like

Origin blog.csdn.net/m0_48465196/article/details/128412011