vue 구성 요소 간에 서로 값을 전달하는 방식을 상세히 설명하다

10411 단어 vue구성 요소전가

개요


우리는 모두 Vue가 경량급의 전단 프레임워크로서 그 핵심은 바로 구성 요소화 개발이라는 것을 안다.Vue는 하나의 구성 요소로 구성되어 있으며 구성 요소화는 그의 정수이자 가장 강력한 기능 중의 하나이다.구성 요소 실례의 역할 영역은 서로 독립적이다. 이것은 서로 다른 구성 요소 간의 데이터가 서로 인용할 수 없다는 것을 의미한다.
그러나 실제 프로젝트 개발 과정에서 우리는 다른 구성 요소의 데이터에 접근해야 하기 때문에 구성 요소 통신 문제가 발생한다.vue에서 구성 요소 간의 관계는 부자, 형제, 격대이다.서로 다른 관계를 겨냥하여 데이터 전달을 어떻게 실현하는가가 바로 다음에 이야기할 것이다.

1. 상위 어셈블리가 하위 어셈블리에 값을 전달합니다.


즉, 부모 구성 요소는 속성을 통해 하위 구성 요소에 값을 전달하고, 하위 구성 요소는props를 통해 수신합니다.
상위 구성 요소의 하위 구성 요소 탭에 사용자 정의 속성 바인딩

//  
<user-detail :myName="name" />
    
export default {
    components: {
        UserDetail
    }
    ......
}
서브어셈블리에서props(그룹일 수도 있고 대상일 수도 있음)로 수신하면 됩니다.여러 속성을 전달할 수 있습니다.

//  
export default {
    props: ['myName']
}
​
/*
props: { myName: String } // , 
props: { myName: [String, Number] } //  
prosp: { myName: { type: String, requires: true } } // 
props: { 
    childMsg: { 
        type: Array, 
        default: () => [] 
    }
}  // default 
  props  , 。
*/
서브어셈블리가 수신하는 상위 어셈블리의 값은 참조 유형과 일반 유형 두 가지로 나뉩니다.
일반 유형: 문자열(String), 숫자(Number), 부울 값(Bolean), 비어있음(Null)
참조 유형: 배열(Array), 객체(Object)
vue 기반의 단방향 데이터 흐름, 즉 구성 요소 간의 데이터는 단방향으로 유통되고 하위 구성 요소는 부모 구성 요소가 전송한 값을 직접 수정할 수 없기 때문에 부모 구성 요소가 전송한 값을 직접 수정하는 작업을 피해야 한다. 그렇지 않으면 컨트롤러가 오류를 보고할 수 있다.
전송된 값이 간단한 데이터 형식이라면 하위 구성 요소에서 수정할 수 있고 다른 형제 구성 요소에서도 이 부모 구성 요소에서 호출된 값에 영향을 주지 않습니다.
구체적인 조작은 먼저 전달된 값을 데이터의 변수에 다시 부여한 다음에 그 변수를 변경할 수 있다.

//  
export default {
    props: ['myName'],
    data() {
        return {
            name : this.myName    //  
        }
    },
    watch: {
        myName(newVal) {
            this.name = newVal // , 
        }
    },
    methods: {
        changeName() {  
            this.name = 'Lily'  //  , 
        },
    }
}
주: 상위 구성 요소가 전달하는 myName 값을 감시하기 위해watch를 사용하지 않으면, 하위 구성 요소의name 값은 상위 구성 요소의 myName 값에 따라 바뀌지 않습니다. 데이터에서name:this.myName은 초기 값만 정의했습니다.
참조 유형의 값이 서브어셈블리에서 수정되면 데이터가 공통이므로 상위 어셈블리의 데이터도 수정됩니다.부모 구성 요소가 하위 구성 요소에 전달하는 값으로 이해할 수 있습니다. 복사본을 복사한 것과 같습니다. 이 복사본의 바늘은 부모 구성 요소의 그것, 즉 같은 인용을 공유하는 것을 가리킵니다.그러니 특별한 수요가 없으면 쉽게 수정하지 마라.

둘째, 서브어셈블리가 상위 어셈블리에 값을 전달합니다.


1. 하위 구성 요소가this.$를 통해 이벤트를 바인딩합니다.emit () 트리거


하위 구성 요소에 이벤트를 연결하고 이 이벤트에 함수를 정의합니다

//  
<button @click="changeParentName"> name</button>
​
export default {
    methods: {
        // 
        changeParentName: function() {
            this.$emit('handleChange', 'Jack') //  handleChange Jack
            //  : 
        }
    }
}
상위 구성 요소에서 handleChange 이벤트 정의 및 바인딩

//  
<child @handleChange="changeName"></child>
​
methods: {
    changeName(name) {  // name Jack
        this.name = name
    }
}

2. 콜백 함수를 통해


부모 구성 요소에 콜백 함수를 정의하고 콜백 함수를 전달합니다

//  
<child :callback="callback"></child>
​
methods: {
    callback: function(name) {
        this.name = name
    }
}
서브어셈블리에서 수신하고callback 함수를 실행합니다

//  
<button @click="callback('Jack')"> name</button>
​
props: {
    callback: Function,
}

3. $parent/$children 또는 $refs를 통해 구성 요소 실례에 접근


이 두 가지는 모두 구성 요소의 실례를 직접 얻어 사용한 후에 구성 요소를 직접 호출할 수 있는 방법이나 데이터에 접근할 수 있다.

//  
export default {
  data () {
    return {
      title: ' '
    }
  },
  methods: {
    sayHello () {
        console.log('Hello');
    }
  }
}

//  
<template>
  <child ref="childRef" />
</template>
​
<script>
  export default {
    created () {
      //   $ref  
      console.log(this.$refs.childRef.title);  //  
      this.$refs.childRef.sayHello(); // Hello
      
      //   $children  
      this.$children.sayHello(); // Hello 
    }
  }
</script>
주: 이런 방식의 구성 요소 통신은 등급을 뛰어넘을 수 없습니다.

3. 형제 구성 요소 간 전가


1. $emit와 props를 결합하는 방식


부모 구성 요소에서 값을 전달할 두 형제 구성 요소에 전달할 변수를 연결하고 이벤트를 정의합니다

//  
<child-a :myName="name" />
<child-b :myName="name" @changeName="editName" />  
    
export default {
    data() {
        return {
            name: 'John'
        }
    },
    components: {
        'child-a': ChildA,
        'child-b': ChildB,
    },
    methods: {
        editName(name) {
            this.name = name
        },
    }
}
서브어셈블리 B에서 변수 및 바인딩 트리거 이벤트 수신

// child-b  
<p> :{{ myName }}</p>
<button @click="changeName"> </button>
    
<script>
export default {
    props: ["myName"],
    methods: {
        changeName() {
            this.$emit('changeName', 'Lily')   //  
        }
    }
}
</script>

// child-a  
<p> :{{ newName }}</p>
    
<script>
export default {
    props: ["myName"],
    computed: {
        newName() {
            if(this.myName) { //  
                return this.myName
            }
            return 'John' // 
        }
    }
}
</script>
즉, 하위 구성 요소 B가 $emit () 를 통해 상위 구성 요소의 이벤트 함수editName을 터치하여 상위 구성 요소의 변수name 값을 바꾸면, 상위 구성 요소는 변경된 값을props를 통해 하위 구성 요소 A에 전달하여 형제 구성 요소 간의 데이터 전달을 실현할 수 있습니다.

2. 빈 vue 실례를 통해


EventBus 만들기js 파일, 그리고 vue 실례 노출

import Vue from 'Vue'
export default new Vue()
값을 전달할 파일에서 이 빈 vue 실례를 가져오고 이벤트를 연결하고 $emit를 통해 이벤트 함수를 터치합니다
(main.js에서 이 js 파일을 전체적으로 도입할 수도 있습니다. 저는 일반적으로 사용해야 할 구성 요소에 도입합니다.)

<template>
    <div>
        <p> : {{ name }}</p>
        <button @click="changeName"> </button>
    </div>
</template>
​
<script>
import { EventBus } from "../EventBus.js"
​
export default {
 data() {
     return {
         name: 'John',
     }
  },
  methods: {
      changeName() {
          this.name = 'Lily'
          EventBus.$emit("editName", this.name) //  , 
      }
    }
}
</script>
전송 값을 받는 구성 요소에서도 vue 실례를 가져옵니다. $on을 통해 리셋을 감청하고, 리셋 함수를 통해 모든 트리거 이벤트가 실행될 때 전송되는 인자를 수신합니다.

import { EventBus } from "../EventBus.js"
​
export default {
    data() {
        return {
            name: ''
        }
    },
    created() {
         EventBus.$on('editName', (name) => {
             this.name = name
         })
    }
}
빈 vue 실례를 만드는 방식은 이벤트 센터를 만들거나 중계소를 만들어 이벤트를 전달하고 수신하는 것과 같다.이런 방식은 모든 구성 요소 간의 통신에도 적용된다. 부자, 형제, 등급을 포함하여 통신 수요가 간단한 프로젝트는 비교적 편리하지만 더욱 복잡한 상황이나 프로젝트가 비교적 크면 vue가 제공하는 더욱 복잡한 상태 관리 모델인 Vuex를 사용하여 처리할 수 있다.

4, 다중 계층 상위 어셈블리 통신


때때로 통신을 실현해야 하는 두 개의 구성 요소는 직접적인 부자 구성 요소가 아니라 할아버지와 손자이거나 더 많은 등급을 뛰어넘는 부자 구성 요소이다. 이럴 때 하위 구성 요소에서 한 등급씩 파라미터를 전달할 수 없다. 특히 구성 요소의 등급이 깊고 끼워넣는 것이 많은 상황에서 전달해야 할 사건과 속성이 많아 코드가 혼란스러울 수 있다.
이 때 vue가 제공하는 더 높은 방법:provide/inject를 사용해야 합니다.
이 옵션은 조상의 구성 요소가 모든 자손에게 의존을 주입할 수 있도록 함께 사용해야 한다. 구성 요소의 차원이 아무리 깊든지 상하류 관계가 성립되는 시간에 시종 효력이 발생한다.
provide/inject: 간단하게 말하자면 부모 구성 요소에서provider를 통해 변수를 제공한 다음에 하위 구성 요소에서inject를 통해 변수를 주입합니다. 구성 요소의 등급이 얼마나 깊든지 상관없이 부모 구성 요소가 효력이 발생하는 생명 주기 내에 이 변수는 계속 유효합니다.
상위 어셈블리:

export default {
  provide: { //   **name**  。
    name: 'Jack'
  }
}
서브어셈블리:

export default {
  inject: ['name'], //  name 
  mounted () {
    console.log(this.name);  // Jack
  }
}
주:provide와 inject 연결은 응답할 수 없습니다.즉, 부모 구성 요소의name가 변하면 하위 구성 요소는 따라서 변하지 않습니다.
provide와 inject 데이터 응답을 실현하려면 두 가지 방법이 있습니다.
provide 조상 구성 요소의 실례를 주입한 다음에 자손 구성 요소에 의존을 주입하면 후손 구성 요소에서 조상 구성 요소의 실례 속성을 직접 수정할 수 있다. 그러나 이런 방법은 이 실례에 불필요한 많은 것을 마운트하는 단점이 있다. 예를 들어props,methods

//   
<div>
      <button @click="changeName"> </button>
      <child-b />
</div>
<script>
    ......
    data() {
        return {
            name: "Jack"
        };
    },
    provide() {
        return {
            parentObj: this // 
        };
    },
    methods: {
        changeName() {
            this.name = 'Lily'
        }
    }
</script>
후대 어셈블리에서 값:

<template>
  <div class="border2">
    <P> :{{parentObj.name}}</P>
  </div>
</template>
<script>
  export default {
    inject: {
      parentObj: {
        default: () => ({})
      }
    } //  inject: ['parentObj']
  };
</script>
주: 이런 방식은 함수식 구성 요소에서 비교적 많이 사용된다.함수식 구성 요소, 즉 무상태(응답식 데이터 없음), 실례화(this 상하문 없음), 내부에도 생명주기 처리 방법이 없기 때문에 렌더링 성능이 높고 외부 데이터 전달에 의존하여 변화하는 구성 요소에 비교적 적합하다.

총결산


부자 통신: 아버지가 자식에게 데이터를 전달하는 것은props를 통해, 아버지가 아버지에게 $emit를 통해;$parent/$children으로 통신하기; $ref도 구성 요소 실례에 접근할 수 있습니다.provide/inject ;$attrs/$listeners;
형제 통신: EventBus;Vuex;
크로스 레벨 통신: EventBus;Vuex;provide/inject ;$attrs/$listeners;
이상은 vue 구성 요소 간의 상호 값 전달 방식에 대한 상세한 내용입니다. vue에 대한 더 많은 자료는 저희 다른 관련 글에 주목하십시오!

좋은 웹페이지 즐겨찾기