Vue 구성 요소 간에 어떻게 통신하나요? 다음 글에서는 Vue 컴포넌트 통신의 6가지 방법을 소개하겠습니다. 도움이 되길 바랍니다!
구성 요소는 vue.js의 가장 강력한 기능 중 하나이며 구성 요소 인스턴스의 범위는 서로 독립적입니다. 즉, 서로 다른 구성 요소 간의 데이터가 서로 참조할 수 없습니다. 일반적으로 구성 요소는 여러 관계를 가질 수 있습니다.
다양한 사용 시나리오에 효과적인 통신 방법을 선택하는 방법은 무엇입니까? 이것이 우리가 탐구할 주제입니다. 이 글에서는 props, Emit/Emit/On, Vuex, Parent/Parent/Children, Attrs/attrs/Listeners, Provide/Inject 등 Vue 구성요소 간 통신의 여러 방법을 요약하고 이해하기 쉬운 예제를 통해 차이점을 설명합니다. . 및 사용 시나리오가 친구들에게 도움이 되기를 바랍니다. [관련 권장사항: vuejs 비디오 튜토리얼, 웹 프론트엔드 개발]
부모 컴포넌트 A는 props를 통해 자식 컴포넌트 B에 전달되고, B에서 A는 B 컴포넌트에서 $emit를 전달합니다. , 컴포넌트 A의 v-on에 의해 구현됩니다.
다음으로, 상위 구성 요소가 하위 구성 요소에 값을 전달하는 방법을 설명하는 예를 사용합니다. 하위 구성 요소에서 상위 구성 요소 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: 'App', 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: 'HelloWorld', props:{ users:{ //这个就是父组件中子标签自定义名字 type:Array, required:true } } } </script>
요약: 상위 구성 요소는 소품을 통해 하위 구성 요소에 데이터를 전달합니다. 참고: 구성 요소에는 데이터, 소품, 계산의 세 가지 형태의 데이터가 있습니다
다음으로 하위 구성 요소가 값을 전달하는 방법을 예시를 사용하여 살펴보겠습니다. 구성 요소가 값을 전달합니다. "Vue.js Demo"를 클릭하면 하위 구성 요소가 값을 상위 구성 요소에 전달하고 텍스트가 원래 "값이 전달되었습니다"에서 "하위가 값을 전달합니다"로 변경됩니다. 상위 구성 요소로", 하위 구성 요소를 상위 구성 요소로 구현합니다. 구성 요소 값을 전달합니다.
// 子组件 <template> <header> <h1 @click="changeTitle">{{title}}</h1>//绑定一个点击事件 </header> </template> <script> export default { name: 'app-header', 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: 'App', data(){ return{ title:"传递的是一个值" } }, methods:{ updateTitle(e){ //声明这个函数 this.title = e; } }, components:{ "app-header":Header, } } </script>
요약: 하위 구성 요소는 이벤트를 통해 상위 구성 요소에 메시지를 보냅니다. 실제로 하위 구성 요소는 자체 데이터를 상위 구성 요소로 보냅니다.
$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: '#a', data() { return { name: 'tom' } }, methods: { send() { Event.$emit('data-a', this.name); } } } var B = { template: '#b', data() { return { age: 20 } }, methods: { send() { Event.$emit('data-b', this.age); } } } var C = { template: '#c', data() { return { name: '', age: "" } }, mounted() {//在模板编译完成后执行 Event.$on('data-a',name => { this.name = name;//箭头函数内部不会产生新的this,这边如果不用=>,this指代Event }) Event.$on('data-b',age => { this.age = age; }) } } var vm = new Vue({ el: '#itany', components: { 'my-a': A, 'my-b': B, 'my-c': C } }); </script>
$on
let defaultCity = "上海" try { // 用户关闭了本地存储功能,此时在外层加个try...catch if (!defaultCity){ defaultCity = JSON.parse(window.localStorage.getItem('defaultCity')) } }catch(e){} export default new Vuex.Store({ state: { city: defaultCity }, mutations: { changeCity(state, city) { state.city = city try { window.localStorage.setItem('defaultCity', JSON.stringify(state.city)); // 数据改变的时候把数据拷贝一份保存到localStorage里面 } catch (e) {} } } })
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('defaultCity')) } }catch(e){} export default new Vuex.Store({ state: { city: defaultCity }, mutations: { changeCity(state, city) { state.city = city try { window.localStorage.setItem('defaultCity', JSON.stringify(state.city)); // 数据改变的时候把数据拷贝一份保存到localStorage里面 } catch (e) {} } } })
这里需要注意的是:由于vuex里,我们保存的状态,都是数组,而localStorage只支持字符串,所以需要用JSON转换:
JSON.stringify(state.subscribeList); // array -> string JSON.parse(window.localStorage.getItem("subscribeList")); // string -> array 复制代码
1.简介
多级组件嵌套需要传递数据时,通常使用的方法是通过vuex。但如果仅仅是传递数据,而不做中间处理,使用 vuex 处理,未免有点大材小用。为此Vue2.4 版本提供了另一种方法----listeners
=