>  기사  >  웹 프론트엔드  >  Vue 구성요소 간에 어떻게 통신하나요? 6가지 방법에 대한 간략한 분석

Vue 구성요소 간에 어떻게 통신하나요? 6가지 방법에 대한 간략한 분석

PHPz
PHPz앞으로
2023-03-22 16:54:171540검색

Vue 구성 요소 간에 어떻게 통신하나요? 다음 글에서는 Vue 컴포넌트 통신의 6가지 방법을 소개하겠습니다. 도움이 되길 바랍니다!

Vue 구성요소 간에 어떻게 통신하나요? 6가지 방법에 대한 간략한 분석

구성 요소는 vue.js의 가장 강력한 기능 중 하나이며 구성 요소 인스턴스의 범위는 서로 독립적입니다. 즉, 서로 다른 구성 요소 간의 데이터가 서로 참조할 수 없습니다. 일반적으로 구성 요소는 여러 관계를 가질 수 있습니다.

다양한 사용 시나리오에 효과적인 통신 방법을 선택하는 방법은 무엇입니까? 이것이 우리가 탐구할 주제입니다. 이 글에서는 props, Emit/Emit/On, Vuex, Parent/Parent/Children, Attrs/attrs/Listeners, Provide/Inject 등 Vue 구성요소 간 통신의 여러 방법을 요약하고 이해하기 쉬운 예제를 통해 차이점을 설명합니다. . 및 사용 시나리오가 친구들에게 도움이 되기를 바랍니다. [관련 권장사항: vuejs 비디오 튜토리얼, 웹 프론트엔드 개발]

방법 1, props/$emit

부모 컴포넌트 A는 props를 통해 자식 컴포넌트 B에 전달되고, B에서 A는 B 컴포넌트에서 $emit를 전달합니다. , 컴포넌트 A의 v-on에 의해 구현됩니다.

1. 상위 구성 요소가 하위 구성 요소에 값을 전달합니다.

다음으로, 상위 구성 요소가 하위 구성 요소에 값을 전달하는 방법을 설명하는 예를 사용합니다. 하위 구성 요소에서 상위 구성 요소 App.vue의 데이터 사용자를 얻는 방법 component Users.vue :["Henry","Bucky","Emily"]

//App.vue父组件
<template>
  <div id="app">
    <users v-bind:users="users"></users>//前者自定义名称便于子组件调用,后者要传递数据名
  </div>
</template>
<script>
import Users from "./components/Users"
export default {
  name: &#39;App&#39;,
  data(){
    return{
      users:["Henry","Bucky","Emily"]
    }
  },
  components:{
    "users":Users
  }
}
//users子组件
<template>
  <div class="hello">
    <ul>
      <li v-for="user in users">{{user}}</li>//遍历传递过来的值,然后呈现到页面
    </ul>
  </div>
</template>
<script>
export default {
  name: &#39;HelloWorld&#39;,
  props:{
    users:{           //这个就是父组件中子标签自定义名字
      type:Array,
      required:true
    }
  }
}
</script>

요약: 상위 구성 요소는 소품을 통해 하위 구성 요소에 데이터를 전달합니다. 참고: 구성 요소에는 데이터, 소품, 계산의 세 가지 형태의 데이터가 있습니다

2. 하위 구성 요소는 이벤트를 통해 상위 구성 요소에 값을 전달합니다

다음으로 하위 구성 요소가 값을 전달하는 방법을 예시를 사용하여 살펴보겠습니다. 구성 요소가 값을 전달합니다. "Vue.js Demo"를 클릭하면 하위 구성 요소가 값을 상위 구성 요소에 전달하고 텍스트가 원래 "값이 전달되었습니다"에서 "하위가 값을 전달합니다"로 변경됩니다. 상위 구성 요소로", 하위 구성 요소를 상위 구성 요소로 구현합니다. 구성 요소 값을 전달합니다.

// 子组件
<template>
  <header>
    <h1 @click="changeTitle">{{title}}</h1>//绑定一个点击事件
  </header>
</template>
<script>
export default {
  name: &#39;app-header&#39;,
  data() {
    return {
      title:"Vue.js Demo"
    }
  },
  methods:{
    changeTitle() {
      this.$emit("titleChanged","子向父组件传值");//自定义事件  传递值“子向父组件传值”
    }
  }
}
</script>
// 父组件
<template>
  <div id="app">
    <app-header v-on:titleChanged="updateTitle" ></app-header>//与子组件titleChanged自定义事件保持一致
   // updateTitle($event)接受传递过来的文字
    <h2>{{title}}</h2>
  </div>
</template>
<script>
import Header from "./components/Header"
export default {
  name: &#39;App&#39;,
  data(){
    return{
      title:"传递的是一个值"
    }
  },
  methods:{
    updateTitle(e){   //声明这个函数
      this.title = e;
    }
  },
  components:{
   "app-header":Header,
  }
}
</script>

요약: 하위 구성 요소는 이벤트를 통해 상위 구성 요소에 메시지를 보냅니다. 실제로 하위 구성 요소는 자체 데이터를 상위 구성 요소로 보냅니다.

방법 2, $emit/$on$emit/$on

这种方法通过一个空的Vue实例作为中央事件总线(事件中心),用它来触发事件和监听事件,巧妙而轻量地实现了任何组件间的通信,包括父子、兄弟、跨级。当我们的项目比较大时,可以选择更好的状态管理解决方案vuex。

1.具体实现方式:

    var Event=new Vue();
    Event.$emit(事件名,数据);
    Event.$on(事件名,data => {});

2.举个例子

假设兄弟组件有三个,分别是A、B、C组件,C组件如何获取A或者B组件的数据

<div id="itany">
	<my-a></my-a>
	<my-b></my-b>
	<my-c></my-c>
</div>
<template id="a">
  <div>
    <h3>A组件:{{name}}</h3>
    <button @click="send">将数据发送给C组件</button>
  </div>
</template>
<template id="b">
  <div>
    <h3>B组件:{{age}}</h3>
    <button @click="send">将数组发送给C组件</button>
  </div>
</template>
<template id="c">
  <div>
    <h3>C组件:{{name}},{{age}}</h3>
  </div>
</template>
<script>
var Event = new Vue();//定义一个空的Vue实例
var A = {
	template: &#39;#a&#39;,
	data() {
	  return {
	    name: &#39;tom&#39;
	  }
	},
	methods: {
	  send() {
	    Event.$emit(&#39;data-a&#39;, this.name);
	  }
	}
}
var B = {
	template: &#39;#b&#39;,
	data() {
	  return {
	    age: 20
	  }
	},
	methods: {
	  send() {
	    Event.$emit(&#39;data-b&#39;, this.age);
	  }
	}
}
var C = {
	template: &#39;#c&#39;,
	data() {
	  return {
	    name: &#39;&#39;,
	    age: ""
	  }
	},
	mounted() {//在模板编译完成后执行
	Event.$on(&#39;data-a&#39;,name => {
	     this.name = name;//箭头函数内部不会产生新的this,这边如果不用=>,this指代Event
	})
	Event.$on(&#39;data-b&#39;,age => {
	     this.age = age;
	})
	}
}
var vm = new Vue({
	el: &#39;#itany&#39;,
	components: {
	  &#39;my-a&#39;: A,
	  &#39;my-b&#39;: B,
	  &#39;my-c&#39;: C
	}
});	
</script>

$on

이 방법은 빈 Vue 인스턴스를 중앙 이벤트 버스(이벤트 센터)로 사용합니다. 이벤트를 트리거하고 이벤트를 모니터링하여 아버지-아들, 형제 및 교차 수준을 포함한 모든 구성 요소 간의 통신을 영리하고 가볍게 구현합니다. 프로젝트 규모가 상대적으로 클 경우 더 나은 상태 관리 솔루션인 vuex를 선택할 수 있습니다.

1. 구체적인 구현 방법:

let defaultCity = "上海"
try {   // 用户关闭了本地存储功能,此时在外层加个try...catch
  if (!defaultCity){
    defaultCity = JSON.parse(window.localStorage.getItem(&#39;defaultCity&#39;))
  }
}catch(e){}
export default new Vuex.Store({
  state: {
    city: defaultCity
  },
  mutations: {
    changeCity(state, city) {
      state.city = city
      try {
      window.localStorage.setItem(&#39;defaultCity&#39;, JSON.stringify(state.city));
      // 数据改变的时候把数据拷贝一份保存到localStorage里面
      } catch (e) {}
    }
  }
})
Vue 구성요소 간에 어떻게 통신하나요? 6가지 방법에 대한 간략한 분석2. 예를 들어

A, B, C 구성 요소가 있다고 가정합니다. C 구성 요소는 A 또는 B 구성 요소의 데이터를 어떻게 얻습니까? >$ on은 사용자 정의 이벤트 data-a 및 data-b를 수신합니다. 이벤트가 언제 트리거될지 확실하지 않기 때문에 일반적으로 마운트되거나 생성된 후크에서 모니터링됩니다.

🎜🎜방법 3, vuex🎜🎜🎜🎜🎜🎜1. Vuex의 원리를 간략하게 소개합니다. Vuex는 단방향 데이터 흐름을 구현하고 데이터를 전체적으로 저장하는 상태를 가지고 있습니다. 구성 요소가 상태의 데이터를 변경하려는 경우 Mutation을 통해 수행해야 합니다. 또한 Mutation은 외부 플러그인이 호출할 수 있는 구독자 모드를 제공합니다. 상태 데이터에 대한 업데이트를 얻습니다. 모든 비동기 작업(업데이트된 데이터를 비동기식으로 얻기 위해 일반적으로 백엔드 인터페이스라고 함) 또는 일괄 동기 작업에 Action이 필요한 경우 Action은 State를 직접 수정할 수 없으며 상태 데이터는 여전히 Mutation을 통해 수정해야 합니다. 마지막으로 State의 변경 사항에 따라 뷰에 렌더링됩니다. 🎜

2.简要介绍各模块在流程中的功能: Vue Components:Vue组件。HTML页面上,负责接收用户操作等交互行为,执行dispatch方法触发对应action进行回应。 dispatch:操作行为触发方法,是唯一能执行action的方法。 actions:操作行为处理模块,由组件中的$store.dispatch('action 名称', data1)来触发。然后由commit()来触发mutation的调用 , 间接更新 state。负责处理Vue Components接收到的所有交互行为。包含同步/异步操作,支持多个同名方法,按照注册的顺序依次触发。向后台API请求的操作就在这个模块中进行,包括触发其他action以及提交mutation的操作。该模块提供了Promise的封装,以支持action的链式触发。 commit:状态改变提交操作方法。对mutation进行提交,是唯一能执行mutation的方法。 mutations:状态改变操作方法,由actions中的commit('mutation 名称')来触发。是Vuex修改state的唯一推荐方法。该方法只能进行同步操作,且方法名只能全局唯一。操作之中会有一些hook暴露出来,以进行state的监控等。 state:页面状态管理容器对象。集中存储Vue components中data对象的零散数据,全局唯一,以进行统一的状态管理。页面显示所需的数据从该对象中进行读取,利用Vue的细粒度数据响应机制来进行高效的状态更新。 getters:state对象读取方法。图中没有单独列出该模块,应该被包含在了render中,Vue Components通过该方法读取全局state对象。 3.Vuex与localStorage vuex 是 vue 的状态管理器,存储的数据是响应式的。但是并不会保存起来,刷新之后就回到了初始状态,具体做法应该在vuex里数据改变的时候把数据拷贝一份保存到localStorage里面,刷新之后,如果localStorage里有保存的数据,取出来再替换store里的state。

let defaultCity = "上海"
try {   // 用户关闭了本地存储功能,此时在外层加个try...catch
  if (!defaultCity){
    defaultCity = JSON.parse(window.localStorage.getItem(&#39;defaultCity&#39;))
  }
}catch(e){}
export default new Vuex.Store({
  state: {
    city: defaultCity
  },
  mutations: {
    changeCity(state, city) {
      state.city = city
      try {
      window.localStorage.setItem(&#39;defaultCity&#39;, JSON.stringify(state.city));
      // 数据改变的时候把数据拷贝一份保存到localStorage里面
      } catch (e) {}
    }
  }
})

这里需要注意的是:由于vuex里,我们保存的状态,都是数组,而localStorage只支持字符串,所以需要用JSON转换:

JSON.stringify(state.subscribeList);   // array -> string
JSON.parse(window.localStorage.getItem("subscribeList"));    // string -> array 
复制代码

方法四、attrs/attrs/listeners

1.简介

多级组件嵌套需要传递数据时,通常使用的方法是通过vuex。但如果仅仅是传递数据,而不做中间处理,使用 vuex 处理,未免有点大材小用。为此Vue2.4 版本提供了另一种方法----attrs/attrs/listeners

attrs: pro에 포함되지 않는 상위 범위를 포함합니다. p가 인정함 (and get)의 기능 바인딩(classst y l 제외). 구성 요소가 prop을 선언하지 않으면 모든 상위 스코프 바인딩 ( lass s s s s)가 포함됩니다. style)vbi를 통해 전달될 수 있습니다. nd =

listeners:包含了父作用域中的(不含.native修饰器的)von事件监听器。它可以通过von="listeners:包含了父作用域中的 (不含 .native 修饰器的) v-on 事件监听器。它可以通过 v-on="listeners" 传入内部组件

接下来我们看个跨级通信的例子:

// index.vue
<template>
  <div>
    <h2>浪里行舟</h2>
    <child-com1
      :foo="foo"
      :boo="boo"
      :coo="coo"
      :doo="doo"
      title="前端工匠"
    ></child-com1>
  </div>
</template>
<script>
const childCom1 = () => import("./childCom1.vue");
export default {
  components: { childCom1 },
  data() {
    return {
      foo: "Javascript",
      boo: "Html",
      coo: "CSS",
      doo: "Vue"
    };
  }
};
</script>
// childCom1.vue
<template class="border">
  <div>
    <p>foo: {{ foo }}</p>
    <p>childCom1的$attrs: {{ $attrs }}</p>
    <child-com2 v-bind="$attrs"></child-com2>
  </div>
</template>
<script>
const childCom2 = () => import("./childCom2.vue");
export default {
  components: {
    childCom2
  },
  inheritAttrs: false, // 可以关闭自动挂载到组件根元素上的没有在props声明的属性
  props: {
    foo: String // foo作为props属性绑定
  },
  created() {
    console.log(this.$attrs); // { "boo": "Html", "coo": "CSS", "doo": "Vue", "title": "前端工匠" }
  }
};
</script>
// childCom2.vue
<template>
  <div class="border">
    <p>boo: {{ boo }}</p>
    <p>childCom2: {{ $attrs }}</p>
    <child-com3 v-bind="$attrs"></child-com3>
  </div>
</template>
<script>
const childCom3 = () => import("./childCom3.vue");
export default {
  components: {
    childCom3
  },
  inheritAttrs: false,
  props: {
    boo: String
  },
  created() {
    console.log(this.$attrs); // { "coo": "CSS", "doo": "Vue", "title": "前端工匠" }
  }
};
</script>
// childCom3.vue
<template>
  <div class="border">
    <p>childCom3: {{ $attrs }}</p>
  </div>
</template>
<script>
export default {
  props: {
    coo: String,
    title: String
  }
};
</script>

Vue 구성요소 간에 어떻게 통신하나요? 6가지 방법에 대한 간략한 분석

如上图所示attrs表示没有继承数据的对象,格式为属性名:属性值。Vue2.4提供了attrs表示没有继承数据的对象,格式为{属性名:属性值}。Vue2.4提供了attrs , $listeners 来传递数据与事件,跨级组件之间的通讯变得更简单。

简单来说:attrsattrs与listeners 是两个对象,attrs里存放的是父组件中绑定的非Props属性,attrs 里存放的是父组件中绑定的非 Props 属性,listeners里存放的是父组件中绑定的非原生事件。

方法五、provide/inject

1.简介

Vue2.2.0新增API,这对选项需要一起使用,以允许一个祖先组件向其所有子孙后代注入一个依赖,不论组件层次有多深,并在起上下游关系成立的时间里始终生效。一言而蔽之:祖先组件中通过provider来提供变量,然后在子孙组件中通过inject来注入变量。 provide / inject API 主要解决了跨级组件间的通信问题,不过它的使用场景,主要是子组件获取上级组件的状态,跨级组件间建立了一种主动提供与依赖注入的关系。

2.举个例子

假设有两个组件: A.vue 和 B.vue,B 是 A 的子组件

// A.vue
export default {
  provide: {
    name: &#39;浪里行舟&#39;
  }
}
// B.vuee
xport default {
  inject: [&#39;name&#39;],  mounted () {
    console.log(this.name);  // 浪里行舟
  }
}

可以看到,在 A.vue 里,我们设置了一个 provide: name,值为 浪里行舟,它的作用就是将 name 这个变量提供给它的所有子组件。而在 B.vue 中,通过 inject 注入了从 A 组件中提供的 name 变量,那么在组件 B 中,就可以直接通过 this.name 访问这个变量了,它的值也是 浪里行舟。这就是 provide / inject API 最核心的用法。

需要注意的是:provide 和 inject 绑定并不是可响应的。这是刻意为之的。然而,如果你传入了一个可监听的对象,那么其对象的属性还是可响应的----vue官方文档 所以,上面 A.vue 的 name 如果改变了,B.vue 的 this.name 是不会改变的,仍然是 浪里行舟。

方法六、parent/parent /children与 ref

ref:如果在普通的 DOM 元素上使用,引用指向的就是 DOM 元素;如果用在子组件上,引用就指向组件实例parent/parent /children:访问父 / 子实例 需要注意的是:这两种都是直接得到组件实例,使用后可以直接调用组件的方法或访问数据。我们先来看个用 ref来访问组件的例子

// component-a 子组件
export default {
  data () {
    return {
      title: &#39;Vue.js&#39;
    }
  },
  methods: {
    sayHello () {
      window.alert(&#39;Hello&#39;);
    }
  }
}
// 父组件
<template>
  <component-a ref="comA"></component-a>
</template>
<script>
  export default {
    mounted () {
      const comA = this.$refs.comA;
      console.log(comA.title);  // Vue.js
      comA.sayHello();  // 弹窗
    }
  }
</script>
复制代码

不过,这两种方法的弊端是,无法在跨级或兄弟间通信

(学习视频分享:vuejs入门教程编程基础视频

위 내용은 Vue 구성요소 간에 어떻게 통신하나요? 6가지 방법에 대한 간략한 분석의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

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