Vue2父子传参:props
首先在父组件中引入子组件,然后以属性的方式将数据传递给子组件
父组件:
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 
 | <template><div class="home">
 
 <HelloWorld :msg="fatchData" ref="childEl"/>
 </div>
 </template>
 
 <script>
 
 import HelloWorld from '@/components/HelloWorld.vue'
 
 export default {
 name: 'Home',
 components: {
 HelloWorld
 },
 data () {
 return {
 fatchData: '我是父组件通过props传递给子组件的文字'
 }
 }
 }
 </script>
 
 | 
然后在子组件中使用props接收,props里定义的名字要和父组件定义的一致
子组件:
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 
 | <template><div>
 <span>{{ msg }}</span>
 </div>
 </template>
 
 <script>
 export default {
 name: 'HelloWorld',
 
 props: {
 msg: String
 }
 }
 </script>
 
 | 
Vue2父子传参之父传子:$refs
在父组件中给子组件的标签上添加 ref 等于一个变量,然后通过使用 $refs 可以获取子组件的实例,以及调用子组件的方法和传递参数
父组件:
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 
 | <template><div class="home">
 
 <HelloWorld :msg="fatchData" ref="childEl"/>
 <div>
 父组件
 </div>
 <div>
 <button @click="changeChildMsg">父组件按钮</button>
 </div>
 </div>
 </template>
 <script>
 import HelloWorld from '@/components/HelloWorld.vue'
 export default {
 name: 'Home',
 components: {
 HelloWorld
 },
 data () {
 return {
 fatchData: '我是父组件通过props传递给子组件的文字'
 }
 },
 methods: {
 
 changeChildMsg () {
 this.fatchData = '通过按钮修改了子组件中显示的问题'
 
 this.$refs.childEl.showText('我来自父组件')
 }
 }
 }
 </script>
 
 | 
然后在子组件中定义相同的方法名,在父组件使用 $refs 调用后触发在子组件中定义的同名方法
子组件:
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 
 | <template><div class="hello">
 <b>子组件</b>
 <div>
 <span>{{ msg }}</span>
 </div>
 <div>
 <button>子组件按钮</button>
 </div>
 </div>
 </template>
 
 <script>
 export default {
 name: 'HelloWorld',
 
 props: {
 msg: String
 },
 methods: {
 
 showText (text) {
 alert(text)
 }
 }
 }
 </script>
 
 | 
Vue2父子传参之子传父:$emit
在子组件中我们也可以调用父组件的方法向父组件传递参数,通过$emit来实现
子组件:
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 
 | <button @click="childClick">子组件按钮</button>
 <script>
 export default {
 name: 'HelloWorld',
 methods: {
 
 childClick () {
 this.$emit('setValueName', '我是通过子组件传递过来的')
 }
 }
 }
 </script>
 
 | 
然后在父组件中定义并绑定子组件传递的 setValueName 事件,事件名称要和子组件定义的名称一样
父组件:
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 
 | <HelloWorld  @setValueName="setValueName" />
 <script>
 import HelloWorld from '@/components/HelloWorld.vue'
 export default {
 name: 'Home',
 components: {
 HelloWorld
 },
 methods: {
 
 setValueName (data) {
 alert(data)
 }
 }
 }
 </script>
 
 | 
Vue2父子传参:parent/children
- 父组件通过$children获取子组件的实例数组
- 子组件通过$parent获取的父组件实例
父组件中可以存在多个子组件,所以this.$children获取到的是子组件的数组
父组件:
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 
 | <HelloWorld /><button @click="getSon">children/parent</button>
 
 <script>
 import HelloWorld from '@/components/HelloWorld.vue'
 
 export default {
 name: 'Home',
 components: {
 HelloWorld
 },
 data () {
 return {
 parentTitle: '我是父组件'
 }
 },
 methods: {
 
 parentHandle () {
 console.log('我是父组件的方法')
 },
 
 getSon () {
 console.log(this.$children)
 console.log(this.$children[0].sonTitle)
 this.$children[0].sonHandle()
 }
 }
 }
 </script>
 
 | 
子组件:
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 
 | <button @click="getParent">获取父组件的方法和值</button><script>
 export default {
 name: 'HelloWorld',
 data () {
 return {
 sonTitle: '我是子组件'
 }
 },
 methods: {
 
 sonHandle () {
 console.log('我是子组件的方法')
 },
 
 getParent () {
 console.log(this.$parent)
 console.log(this.$parent.parentTitle)
 this.$parent.parentHandle()
 }
 }
 }
 </script>
 
 | 
Vue2兄弟传参:bus.js
首先新建 bus.js 文件,初始化如下代码:
| 12
 
 | import Vue from 'vue'export default new Vue()
 
 | 
然后在需要通信的组件中都引入该 bus 文件,其中一个文件用来发送,一个文件监听接收。派发事件使用 bus.$emit。
下面组件派发了一个叫setYoungerBrotherData的事件
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 
 | <template><div>
 哥哥组件:<button @click="setYoungerBrotherData">给弟弟传参</button>
 </div>
 </template>
 <script>
 import bus from '../assets/bus'
 export default {
 methods: {
 setYoungerBrotherData () {
 
 bus.$emit('setYoungerBrotherData', '给弟弟传参')
 }
 }
 }
 </script>
 
 | 
在另一个页面中使用 bus.$on('setYoungerBrotherData',()=>{}) 监听
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 
 | <template><div>弟弟组件:{{ msg }}</div>
 </template>
 <script>
 import bus from '../assets/bus'
 export default {
 data () {
 return {
 msg: ''
 }
 },
 mounted () {
 
 bus.$on('setYoungerBrotherData', (res) => {
 this.msg = res
 })
 }
 }
 </script>
 
 | 
Vue2跨级传参:provide/inject
provide和inject是vue生命周期上的两个函数,这对选项需要一起使用,以允许一个祖先组件向其所有子孙后代注入一个依赖,不论组件层次有多深,并在其上下游关系成立的时间里始终生效。
提示:provide 和 inject 绑定并不是可响应的。这是刻意为之的。然而,如果你传入了一个可监听的对象,那么其对象的 property 还是可响应的。
祖先组件:
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 
 | <script>export default {
 name: 'Home',
 
 provide () {
 return {
 
 provideName: '祖先',
 
 getOrderInfo: () => {
 return this.getOrderList()
 }
 }
 },
 methods: {
 
 getOrderList () {
 return new Promise((resolve, reject) => {
 
 setTimeout(() => {
 resolve({
 code: 'WX15485613548',
 name: '农夫安装工单'
 })
 }, 2000)
 })
 }
 }
 }
 </script>
 
 | 
孙子组件:
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 
 | <template><div>
 {{ bar }}
 <button @click="getOrder">异步获取数据</button>
 </div>
 </template>
 <script>
 export default {
 
 inject: ['provideName', 'getOrderInfo'],
 data () {
 return {
 
 bar: this.provideName
 }
 },
 mounted () {
 console.log(this.provideName)
 },
 methods: {
 getOrder () {
 
 this.getOrderInfo().then(res => {
 console.log(res)
 })
 }
 }
 }
 </script>
 
 
 | 
使用 provide/inject的好处是父组件不需要知道是哪个自组件使用了我的数据,子组件也不需要关心数据从何而来
总结
- 父子通信:父向子传递数据通过props,子向父传递数据通过$emit事件,父链子链使用$parent/$children,直接访问子组件实例使用$refs
- 兄弟通信:bus,Vuex
- 跨级通信:bus,Vuex,provide/inject