Vue组件间的通信
组件间的通信总共有六种方式
-
props(父组件向子组件传值)和$emit(子组件向父组件传值)
-
父组件向子组件传值:props
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <script src="../vue包/vue.js"></script> </head> <body> <div id="app"> <login :parent='msg'></login> //使用v-bind进行属性的绑定 </div> <script> login = { template: '<h1>子组件--{{cmsg}}--{{parent}}</h1>', data() { return { cmsg: '子组件中的data' } }, props: ['parent'] //使用props进行属性的注册 } const vm = new Vue({ el: "#app", data: { msg: '父组件中的data' }, components: { login } }) </script> </body> </html>
-
子组件向父组件传值:$emit
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <script src="../vue包/vue.js"></script> </head> <body> <div id="app"> <h1>父组件中的data:{{dataFromSon}}</h1> <son @func='show'></son> </div> <template id="box"> <div> <h1>子组件</h1> <input type="button" value="子组件向父组件传值" @click='myClick' /> </div> </template> <script> const son = { template: '#box', data() { return { name: 'tu' } }, methods: { myClick() { this.$emit('func', this.name); //使用$emit发送事件的同时将子组件中的数据传给父组件 } } } const vm = new Vue({ el: '#app', data: { dataFromSon: null }, methods: { show(data) { console.log('调用父组件中的show方法' + data); this.dataFromSon = data; } }, components: { son } }) </script> </body> </html>
-
-
EventBus中央事件总线(创建一个空的Vue实例(EventBus),来作为中间站,< e m i t 发 送 事 件 / emit发送事件/ emit发送事件/on监听事件)
(一般用于兄弟组件间的通信。)
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <script src="../vue包/vue.js"></script> </head> <body> <div id="app"> <children-one></children-one> <children-two></children-two> <children-three></children-three> </div> <template id="one"> <div> <h1>one ----- {{name}}</h1> <button @click='send'>传递name数据给three组件</button> </div> </template> <template id="two"> <div> <h1>two -------{{age}}</h1> <button @click='send'>传递age数据给three组件</button> </div> </template> <template id="three"> <div> <h1>three -------{{name}}---{{age}}</h1> </div> </template> <script> // 创建一个空的Vue实例(EventBus),来作为中间站 const EventBus = new Vue(); const childrenOne = { template: '#one', data() { return { name: 'tu' } }, methods: { send() { // 使用EventBus.$emit来发送事件 EventBus.$emit('data-one', this.name); } } } const childrenTwo = { template: '#two', data() { return { age: 18 } }, methods: { send() { EventBus.$emit('data-two', this.age); } } } const childrenThree = { template: '#three', data() { return { name: '', age: '' } }, methods: {}, mounted() { // 使用EventBus.on来监听事件(在钩子mounted中监听) EventBus.$on('data-one', name => { // console.log(this); this.name = name; }); //这里使用箭头函数的意义在于需要将this指向的c组件,如果不使用箭头函数则this指向的是EventBus实例 EventBus.$on('data-two', age => { // console.log(this); this.age = age; }) } } const vm = new Vue({ el: '#app', data: {}, methods: {}, components: { childrenOne, childrenTwo, childrenThree } }) </script> </body> </html>
传值前:
点击按钮进行传值:
-
Vuex实现组件通信(可以实现父子,兄弟组件间的通信)
-
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。每一个 Vuex 应用的核心就是 store(仓库)。
-
Vuex 的状态存储是响应式的。当 Vue 组件从 store 中读取状态的时候,若 store 中的状态发生变化,那么相应的组件也会相应地得到高效更新。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZyObb1xi-1605688900128)(D:\md\images\Vuex.png)]
-
-
ref与$parent / $children实现组件传值 (适用 父子组件通信)
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <script src="../vue包/vue.js"></script> </head> <body> <div id="app"> <!-- 在子组件中使用ref进行标记 --> <son ref='comA'></son> <son2 ref='comB'></son2> </div> <template id="box"> <div> <h1>{{msg}}</h1> <p>{{flag}}</p> </div> </template> <template id="box2"> <div> <h1>{{msg2}}</h1> <p>{{flag2}}</p> </div> </template> <script> const son = { template: '#box', data() { return { msg: '子组件1', flag: true } }, methods: {} } const son2 = { template: '#box2', data() { return { msg2: '子组件2', flag2: false } }, methods: {}, mounted() { // 用$parent获取父组件 console.log(this.$parent); } } const vm = new Vue({ el: '#app', data: {}, methods: {}, components: { son, son2 }, mounted() { // this.$children获取子组件 console.log(this.$children[0].msg); console.log(this.$children[0].flag); console.log(this.$children[1].msg2); console.log(this.$children[1].flag2); console.log('------------------------'); // 也可以使用this.$refs获取子组件,但是必须要使用ref进行组件标记 console.log(this.$refs); console.log(this.$refs.comA); console.log(this.$refs.comB); // 获取数据 console.log(this.$refs.comA.msg); console.log(this.$refs.comA.flag); console.log(this.$refs.comB.msg2); console.log(this.$refs.comB.flag2); } }) </script> </body> </html>
-
$attrs / $listeners进行组件传值(适用于父子组件传值)
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <script src='../vue包/vue.js'></script> </head> <body> <div id="app"> <son :foo='foo' :boo='boo' :coo='coo'></son> </div> <template id="box"> <div> <h1>message</h1> </div> </template> <script> const son = { template: '#box', data() { return {} }, methods: {}, inheritAttrs: false, created() { console.log(this.$attrs); //{foo: "tu", boo: "qiang", coo: "min"} } } const vm = new Vue({ el: '#app', data: { foo: 'tu', coo: 'min', boo: 'qiang' }, methods: {}, components: { son } }) </script> </body> </html>
-
provide和inject进行组件传值(使用与祖先组件先子孙组件传值)
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <script src="../vue包/vue.js"></script> </head> <body> <div id="app"> <son></son> </div> <template id="box"> <div> <h1>{{message}}</h1> </div> </template> <script> const son = { template: '#box', data() { return {} }, methods: {}, inject: ['message'], mounted() { console.log(this.message); } }; const vm = new Vue({ el: "#app", data: {}, methods: {}, components: { son }, provide: { 'message': 'hello' } }); </script> </body> </html>
```data() { return {} }, methods: {}, inject: ['message'], mounted() { console.log(this.message); } }; const vm = new Vue({ el: "#app", data: {}, methods: {}, components: { son }, provide: { 'message': 'hello' } });