>  기사  >  웹 프론트엔드  >  Vue 컴포넌트 통신 방법 소개(코드 포함)

Vue 컴포넌트 통신 방법 소개(코드 포함)

不言
不言앞으로
2019-03-19 10:51:002155검색

이 기사는 Vue 구성 요소(코드 포함)의 통신 방법을 소개합니다. 도움이 필요한 친구들이 참고할 수 있기를 바랍니다.

vue의 컴포넌트화는 핵심 아이디어여야 합니다. 큰 페이지든 작은 버튼이든 컴포넌트라고 할 수 있습니다. Vue 기반 개발은 기본 컴포넌트든 비즈니스 컴포넌트든 컴포넌트를 하나씩 작성하고 결국에는 모두 조립해야 한다는 의미입니다. 컴포넌트의 계층적 관계에 따르면 컴포넌트 간의 관계는 부모-자식 관계, 세대 관계, 형제 관계, 무관계 관계로 요약할 수 있습니다.

$ref, $parent, $children

현재 컨텍스트를 기반으로 $ref, $parent, $children을 통해 컴포넌트 인스턴스에 접근할 수 있으며, 컴포넌트의 메소드를 직접 호출하거나 데이터에 접근할 수 있습니다. 그 중 $parent는 현재 컴포넌트의 상위 컴포넌트에 접근할 수 있고, $children은 현재 컴포넌트의 모든 자식 컴포넌트에 접근할 수 있습니다. $parent와 $children 모두 구성 요소 인스턴스를 얻을 수 있지만 수준 간이나 형제 간에 통신할 수 없다는 것이 단점입니다.

provide 및 inject

provide/inject는 버전 2.2.0 이후 Vue에 추가된 새로운 API입니다.

구성 요소 계층 구조의 깊이에 관계없이 상위 구성 요소가 모든 하위 항목에 종속성을 주입할 수 있도록 하려면 이 옵션 쌍을 함께 사용해야 하며, 업스트림 및 다운스트림 관계가 설정된 시점부터 항상 적용됩니다. .

즉, 상위 구성 요소에 값을 제공하고 사용해야 하는 하위 구성 요소에 변경된 값을 주입합니다. 즉,

// Parent.vue
export default {
    provide() {
        return {
            name: 'Stone'
        }
    }
}
// Child.vue
export default {
   inject: ['name'],
   mounted() {
       console.log(this.name)
   }
}

부모의 하위 구성 요소인 한 Child.vue뿐만 아니라. vue, 아무리 세대가 떨어져 있어도 이 방법을 통해서는 모두 주입이 가능합니다. 이 다중 레벨 구성요소 투명 전송 방법은 단방향 데이터 흐름의 명확성을 보장할 수 있습니다. 예를 들어, 타사 라이브러리 vuex를 도입하지 않고도 이 두 API의 도움으로 사용자 정보와 같은 전역 정보를 완성할 수 있습니다.

Vuex

vuex의 대안은 데이터를 중앙에서 관리하고 필요할 때마다 얻는 것입니다. 이 아이디어에 따라 루트 구성 요소인 App.vue에 전역 정보를 삽입하고 페이지의 어느 곳에서나 사용할 수 있습니다.

// App.vue
<template>
  <div>
    <router-view></router-view>
  </div>
</template>
export default {
    provide() {
        return {
            userInfo: this.user
        }
    },
    data() {
        return {
            user: {}
        }
    },
    methods: {
      getUserInfo () {
        $.ajax('/user/info', (data) => {
          this.user = data
        })
      }
    }
}

전체 App.vue 인스턴스 this를 외부에 제공하여 다른 페이지가 this.userInfo를 통해 사용자 정보를 얻을 수 있도록 합니다. this 对外提供, 这样其他页面就可以通过 this.userInfo 来获取用户信息。

<template>
  <div>
    {{ userInfo }}
  </div>
</template>
<script>
  export default {
    inject: ['userInfo']
  }
</script>

$dispatch 、 $broadcast

这两个 API 是 Vue 1.0 版本的,$dispatch 用于向上级派发事件,$broadcast 用于向下级广播事件的,它们在 2.0 版本中已经被废弃了。

因为基于组件树结构的事件流方式有时让人难以理解,并且在组件结构扩展的过程中会变得越来越脆弱。

不过我们可以自行实现 dispatch 和 broadcast 方法,用于组件的跨层级通信。它们实现的关键在于如何正确找到所要通信的组件,也就是通过匹配组件的 name 选项向下或向上查找组件。

这两个方法都需要传递 3 个参数,第一个参数是要通信组件的 name 选项值,第二个是自定义事件名称,第三个是要给通信组件传递的值。在 dispatch 里,通过 while 循环不断向上查找父组件,直到查找到 componentName 与某个父级组件的 name 选项匹配时结束,此时改父组件就是要通信的组件。 broadcast 方法与 dispatch 类似,是通过 forEach 循环向下查找子组件。 最后封装一个 mixins 来便于复用。

// emitter.js 
function broadcast(componentName, eventName, params) {
  this.$children.forEach(child => {
    const name = child.$options.name;
    if (name === componentName) {
      child.$emit.apply(child, [eventName].concat(params));
    } else {
      broadcast.apply(child, [componentName, eventName].concat([params]));
    }
  });
}
export default {
  methods: {
    dispatch(componentName, eventName, params) {
      let parent = this.$parent || this.$root;
      let name = parent.$options.name;
      while (parent && (!name || name !== componentName)) {
        parent = parent.$parent;
        if (parent) {
          name = parent.$options.name;
        }
      }
      if (parent) {
        parent.$emit.apply(parent, [eventName].concat(params));
      }
    },
    broadcast(componentName, eventName, params) {
      broadcast.call(this, componentName, eventName, params);
    }
  }
};

通过 mixins 混入组件,实现组件间的通信。

<!-- Parent.vue -->
<template>
  <button @click="handleClick">
    触发事件
    <Child></Child>
  </button>
</template>
<script>
import Emitter from "../assets/js/emitter.js";
import Child from "./Child.vue";
export default {
  name: "Parent",
  mixins: [Emitter],
  created() {
    this.$on("on-message", message => {
      console.log(message);
    });
  },
  components: {
    Child
  },
  methods: {
    handleClick() {
      this.broadcast("Child", "on-message", "Hello, I am Parent Component");
    }
  }
};
</script>
<!-- Child.vue -->
<template>
  <div></div>
</template>
<script>
import Emitter from "../assets/js/emitter.js";
export default {
  name: "Child",
  mixins: [Emitter],
  mounted() {
    this.$on("on-message", message => {
      console.log(message);
      this.dispatch("Parent", "on-message", "Copy that, I am Child Component");
    });
  }
};
</script>

相比 Vue 1.0 版本内置的两个 API,自行实现的方法有以下不同:

  • 需要额外传入组件的 name 作为第一个参数;
  • 匹配到组件就会停止循环,不会冒泡;
  • 传递的值只能是一个参数,如果需要传递多个参数,只能通过对象或数组的形式;

其他方法

在 vue 中组件的通信还有其他的手法,例如:

  1. props$emit
    <!-- Parent.vue -->
    <template>
      <Child :info="info"
             @update="onUpdateName"></Child>
    </template>
    <script>
    import Child from "./Child.vue";
    export default {
      data() {
        return {
          info: {
            name: "stone"
          }
        };
      },
      components: {
        Child
      },
      methods: {
        onUpdateName(name) {
          this.info.name = name;
        }
      }
    };
    </script>
  2. $dispatch 및 $broadcast

이 두 API는 Vue 1.0 버전에서 가져온 것입니다. $dispatch는 상위 수준으로 이벤트를 전달하는 데 사용되고 $broadcast는 하위 수준으로 이벤트를 브로드캐스트하는 데 사용됩니다. 버전 2.0.

컴포넌트 트리 구조를 기반으로 한 이벤트 흐름 방식은 때때로 이해하기 어렵고, 컴포넌트 구조가 확장됨에 따라 점점 더 취약해지기 때문입니다.

그러나 구성 요소의 교차 레벨 통신을 위해 디스패치 및 브로드캐스트 방법을 직접 구현할 수 있습니다. 구현의 핵심은 통신할 컴포넌트를 올바르게 찾는 방법, 즉 컴포넌트의 이름 옵션을 일치시켜 아래쪽 또는 위쪽에서 컴포넌트를 찾는 것입니다.

두 메소드 모두 3개의 매개변수를 전달해야 합니다. 첫 번째 매개변수는 통신 구성요소의 이름 옵션 값이고, 두 번째 매개변수는 맞춤 이벤트 이름, 세 번째 매개변수는 통신 구성요소에 전달할 값입니다. 디스패치에서는 componentName이 상위 컴포넌트의 name 옵션과 일치할 때까지 while 루프를 통해 상위 컴포넌트를 검색합니다. 이때 상위 컴포넌트는 통신할 컴포넌트입니다. 브로드캐스트 방법은 forEach 루프를 통해 하위 구성 요소를 아래쪽으로 검색하는 디스패치와 유사합니다. 마지막으로 재사용을 용이하게 하기 위해 믹스인을 캡슐화합니다.

<!-- Child.vue -->
<template>
  <div>
    <div>{{info.name}}</div>
    <button @click="handleUpdate">update</button>
  </div>
</template>
<script>
export default {
  props: {
    info: {
      type: Object,
      default: {}
    }
  },
  methods: {
    handleUpdate() {
      this.$emit("update", "new-name");
    }
  }
};
</script>

믹스인을 통해 구성요소를 혼합하여 구성요소 간의 통신을 구현합니다.

rrreeerrreee

Vue 1.0 버전에 내장된 두 가지 API와 비교했을 때 자체 구현 방식은 다음과 같은 차이점이 있습니다.

구성요소가 일치하면 루프가 중지되고 버블링되지 않습니다.

  • 전달된 값은 하나의 매개변수만 전달할 수 있습니다. 여러 매개변수를 전달해야 하는 경우 객체 또는 형식으로만 전달될 수 있습니다. 배열;

    다른 방법 h2>vue에는 구성요소 통신을 위한 다른 방법이 있습니다: 🎜
    1. props, $ Emit🎜🎜rrreeerrreee🎜상위 구성 요소는 자체적으로 메소드가 하위 구성 요소에 전달되고, 하위 구성 요소는 이벤트 버스 $attrs 및 $listeners를 사용하여 상위 구성 요소에 데이터를 전달하는 메소드를 호출합니다. Vue 2.4의 API. 🎜🎜$attrs에는 소품으로 인식(및 획득)되지 않는 상위 범위의 속성 바인딩(클래스 및 스타일 제외)이 포함되어 있습니다. 🎜🎜$listeners에는 상위 범위의 v-on 이벤트 리스너가 포함되어 있습니다(.native 수정자 없음). Vuex 중앙 집중식 상태 관리🎜🎜마지막에 작성🎜🎜다양한 통신 방법이 다양한 시나리오에 적합합니다. Vue에 내장된 API를 통해 통신할 수도 있고, 애플리케이션이 충분히 복잡할 경우 통신 방법을 구현할 수도 있습니다. 데이터 관리에는 Vuex를 사용하세요. 🎜🎜이 기사는 여기까지입니다. 더 많은 흥미로운 콘텐츠를 보려면 PHP 중국어 웹사이트의 🎜JavaScript Tutorial Video🎜 칼럼을 주목하세요! 🎜🎜 🎜

  • 위 내용은 Vue 컴포넌트 통신 방법 소개(코드 포함)의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

    성명:
    이 기사는 segmentfault.com에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제