Vue2父子传参:props
首先在父组件中引入子组件,然后以属性的方式将数据传递给子组件
父组件:
1 2 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里定义的名字要和父组件定义的一致
子组件:
1 2 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 可以获取子组件的实例,以及调用子组件的方法和传递参数
父组件:
1 2 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
调用后触发在子组件中定义的同名方法
子组件:
1 2 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
来实现
子组件:
1 2 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
事件,事件名称要和子组件定义的名称一样
父组件:
1 2 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
获取到的是子组件的数组
父组件:
1 2 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>
|
子组件:
1 2 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
文件,初始化如下代码:
1 2
| import Vue from 'vue' export default new Vue()
|
然后在需要通信的组件中都引入该 bus
文件,其中一个文件用来发送,一个文件监听接收。派发事件使用 bus.$emit
。
下面组件派发了一个叫setYoungerBrotherData
的事件
1 2 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',()=>{})
监听
1 2 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 还是可响应的。
祖先组件:
1 2 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>
|
孙子组件:
1 2 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