$parent / $children and ref
provide / inject
위 그림과 같이 A/B, B/C, B/D 컴포넌트는 부모-자식입니다. C/D는 형제관계이다. 그렇다면 다양한 사용 시나리오에 따라 다양한 통신 방법을 선택하는 방법은 무엇입니까? 따라서 전제는 다양한 의사소통 방법의 기능과 차이점을 이해해야 한다는 것입니다.
이것은 우리가 일반적으로 더 자주 사용하는 방법 중 하나입니다. 상위 구성 요소 A는 props 매개 변수를 통해 하위 구성 요소 B에 데이터를 전달하고, 구성 요소 B는 $emit를 통해 구성 요소 A에 이벤트를 보냅니다. (매개변수 데이터 전달) 구성요소 A는 B가 A로 전송한 데이터를 얻기 위해 $emit에 의해 트리거된 이벤트를 수신합니다. 구현 단계를 자세히 설명하겠습니다.
// App.vue 父组件 <template> <a-compontent></a-compontent> </template> <script> import aCompontent from './components/A.vue'; export default { name: 'app', compontent: { aCompontent }, data () { return { dataA: 'dataA数据' } } } // aCompontent 子组件 <template> <p>{{dataA}} // 在子组件中把父组件传递过来的值显示出来 <script>export default { name: 'aCompontent', props: { dataA: { //这个就是父组件中子标签自定义名字 type: String, required: true // 或者false } } } </script>
// 子组件 <template> <p>点击向父组件传递数据</p> </template> <script>export default { name: 'child', methods:{ changeTitle() { // 自定义事件,会触发父组件的监听事件,并将数据以参数的形式传递 this.$emit('sendDataToParent','这是子组件向父组件传递的数据'); } } } // 父组件 <template> <child @sendDataToParent="getChildData"> <script> import child from './components/child.vue'; export default { name: 'child', methods:{ getChildData(data) { console.log(data); // 这里的得到了子组件的值 } } } </script>
이 방법은 App.vue와 유사한 인스턴스를 모듈의 이벤트 센터로 사용하여 이벤트를 트리거하고 수신하는 데 사용합니다. App.vue에 넣으면 구성 요소에서 무엇이든 통신할 수 있지만 이 방법은 프로젝트 규모가 상대적으로 크면 유지 관리가 쉽지 않습니다.
예: 이제 Home.vue 및 A/B/C 구성 요소 4개가 있다고 가정합니다. 이 세 가지 구성 요소 AB는 형제 구성 요소입니다. Home.vue는 빈 Vue 인스턴스를 생성하고 통신 이벤트를 중단하는 상위 구성 요소와 동일합니다. . 이 인스턴스에 로드됨 -
D.js import Vue from 'vue'export default new Vue()
// 我们可以在router-view中监听change事件,也可以在mounted方法中监听 // home.vue<template> <p> <child-a></child-a> <child-b></child-b> <child-c></child-c> </p></template>
// A组件 <template> <p>将A组件的数据发送给C组件 - {{name}}</p> </template> <script> import Event from "./D";export default { data() { return { name: 'Echo' } }, components: { Event }, methods: { dataA() { Event.$emit('data-a', this.name); } } } </script>
// B组件 <template> <p>将B组件的数据发送给C组件 - {{age}}</p> </template> <script> import Event from "./D";export default { data() { return { age: '18' } }, components: { Event }, methods: { dataB() { Event.$emit('data-b', this.age); } } } </script>
// C组件 <template> <p>C组件得到的数据 {{name}} {{age}}</p> </template> <script> import Event from "./D";export default { data() { return { name: '', age: '' } }, components: { Event }, mounted() { // 在模板编译完成后执行 Event.$on('data-a', name => { this.name = name; }) Event.$on('data-b', age => { this.age = age; }) } } </script>
위에서 알 수 있듯이 C 구성요소의 마운트된 이벤트에서 A/B의 $emit 이벤트가 모니터링되고 이에 의해 전달된 매개변수를 가져옵니다(언제 실행될지 확실하지 않기 때문). 이벤트가 발생하므로 일반적으로 마운트/생성시 모니터링됩니다)
Vuex는 상태 관리 모델입니다. 중앙 집중식 저장소를 사용하여 애플리케이션의 모든 구성 요소 상태를 관리하고 해당 규칙을 사용하여 상태가 예측 가능한 방식으로 변경되도록 합니다. Vuex 애플리케이션의 핵심은 스토어(창고, 컨테이너)입니다. 스토어에는 애플리케이션의 대부분의 상태가 포함되어 있습니다.
이 부분은 자세히 소개되지 않으며 공식 문서는 매우 상세합니다. vuex.vuejs.org/ zh /guide/st…
위 그림과 같이 A/C 구성 요소가 어떻게 통신하는지 살펴보겠습니다. 이제 다음과 같은 해결책을 생각해 볼 수 있습니다.
Vue2.4에서는 이러한 요구 사항을 해결하기 위해 attrs와 Listener가 도입되었고, InheritAttrs 옵션이 추가되었습니다. (아래 그림 참조)
$attrs의 역할은 경우에 따라 상속 Attrs와 함께 사용해야 합니다.
4가지 구성 요소가 있습니다: App.vue / child1.vue / child2.vue / child3 .vue, 이 4개의 구성 요소는 순서대로 중첩됩니다.
// App.vue <template> <p> </p> <p>App.vue</p> <hr> // 这里我们可以看到,app.vue向下一集的child1组件传递了5个参数,分别是name / age / job / sayHi / title <child1></child1> </template> <script> const child1 = () => import("./components/child1.vue"); export default { name: 'app', components: { child1 }, data() { return { name: "Echo", age: "18", job: "FE", say: "this is Hi~" }; } }; </script>
// child1.vue <template> <p> </p> <p>child1.vue</p> <p>name: {{ name }}</p> <p>childCom1的$attrs: {{ $attrs }}</p> <p>可以看到,$attrs这个对象集合中的值 = 所有传值过来的参数 - props中显示定义的参数</p> <hr> <child2></child2> </template> <script> const child2 = () => import("./child2.vue"); export default { components: { child2 }, // 这个inheritAttrs默认值为true,不定义这个参数值就是true,可手动设置为false // inheritAttrs的意义在用,可以在从父组件获得参数的子组件根节点上,将所有的$attrs以dom属性的方式显示 inheritAttrs: true, // 可以关闭自动挂载到组件根元素上的没有在props声明的属性 props: { name: String // name作为props属性绑定 }, created() { // 这里的$attrs就是所有从父组件传递过来的所有参数 然后 除去props中显式定义的参数后剩下的所有参数!!! console.log(this.$attrs); // 输出{age: "18", job: "FE", say-Hi: "this is Hi~", title: "App.vue的title"} } }; </script>
// child2.vue <template> <p> </p> <p>child2.vue</p> <p>age: {{ age }}</p> <p>childCom2: {{ $attrs }}</p> <hr> <child3></child3> </template> <script> const child3 = () => import("./child3.vue"); export default { components: { child3 }, // 将inheritAttrs设置为false之后,将关闭自动挂载到组件根元素上的没有在props声明的属性 inheritAttrs: false, props: { age: String }, created() { // 同理和上面一样,$attrs这个对象集合中的值 = 所有传值过来的参数 - props中显示定义的参数 console.log(this.$attrs); } }; </script>
// child3.vue <template> <p> </p> <p>child3.vue</p> <p>job: {{job}}</p> <p>title: {{title}}</p> <p>childCom3: {{ $attrs }}</p> </template> <script>export default { inheritAttrs: true, props: { job: String, title: String } }; </script>
구체적인 디스플레이 효과를 살펴보겠습니다.
그리고 $listeners를 사용하는 방법에 대해 공식 문서에는 다음과 같이 나와 있습니다. 상위 범위(.native 수정자 없음) 장치에서 청취하는 v-on 이벤트가 포함되어 있습니다. v-on="$listeners"를 통해 내부 구성요소로 전달될 수 있습니다. 더 높은 수준의 구성요소를 생성할 때 매우 유용합니다! 문자 그대로의 의미에서 값을 수락해야 하는 상위 구성 요소에 청취 이벤트를 추가해야 합니까? 말할 것도 없이, 코드
는 여전히 순서대로 중첩된 3개의 구성요소입니다
<template> <p> <child2></child2> </p> </template> <script> const child2 = () => import("./child2.vue"); export default { components: { child2 }, methods: { reciveRocket() { console.log("reciveRocket success"); } } }; </script>复制代码
<template> <p> <child3></child3> </p> </template> <script> const child3 = () => import("./child3.vue"); export default { components: { child3 }, created() { this.$emit('child2', 'child2-data'); } }; </script>复制代码
// child3.vue <template> <p> </p> <p>child3</p> </template> <script> export default { methods: { startUpRocket() { this.$emit("upRocket"); console.log("startUpRocket"); } } }; </script>复制代码
这里的结果是,当我们点击 child3 组件的 child3 文字,触发 startUpRocket 事件,child1 组件就可以接收到,并触发 reciveRocket 打印结果如下:
> reciveRocket success > startUpRocket
这两种方式都是直接得到组件实例,使用后可以直接调用组件的方法或访问数据。
我们先来看个用 ref 来访问组件的:
// child1子组件 export default { data() { return { title: 'Vue.js' }; }, methods: { sayHello() { console.log('child1!!'); } } };
// 父组件 <template> <child1></child1> </template> <script> export default { methods: { sayHi () { const child1 = this.$refs.child1; console.log(child1.title); // Vue.js child1.sayHello(); // 弹窗 } } } </script>
provide/inject 是 Vue2.2.0 新增 API,这对选项需要一起使用,以允许一个祖先组件向其所有子孙后代注入一个依赖,不论组件层次有多深,并在起上下游关系成立的时间里始终生效。如果你熟悉 React,这与 React 的上下文特性很相似。
provide 和 inject 主要为高阶插件/组件库提供用例。并不推荐直接用于应用程序代码中。
由于自己对这部分的内容理解不是很深刻,所以感兴趣的可以前往官方文档查看: cn.vuejs.org/v2/api/#pro…
常见使用场景可以分为三类:
推荐教程:《JS教程》
위 내용은 Vue 구성요소와 통신하는 6가지 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!