一、父组件传递数据到子组件中(属性传递)
1、父组件
<template> <div> <child01 :names="names" v-if="isLoading"/> </div> </template> <script> import child01 from './child01' export default { data () { return { names: [], isLoading: false } }, methods: { getData () { setTimeout(() => { this.names = ['哈哈', '嘻嘻', '美美'] this.isLoading = true }, 2000) } }, mounted () { this.getData() }, components: { child01 } } </script>
2、子组件
<template> <div> <ul> <li v-for="(item, index) of names" :key="index">{{item}}</li> </ul> </div> </template> <script> export default { props: { names: { type: Array } } } </script>
二、子组件传递值到父组件(方法传递)
1、子组件
<li v-for="(item, index) of names" :key="index" @click="sendVal(item)">{{item}}</li> ... methods: { sendVal (val) { this.$emit('sendVal', val) } } ...
2、父组件
<child01 :names="names" v-if="isLoading" @sendVal="sendVal"/> ... methods: { sendVal (val) { console.log(val) } }, ...
三、父组件调用子组件的方法(直接使用ref
)[也可以获取子组件的属性]
1、子组件
methods: { sendVal (val) { this.$emit('sendVal', val) }, foo () { console.log('我是子组件的方法') } }
2、父组件
foo () { console.log('子组件中的数据===>', this.$refs.child) this.$refs.child.foo() }
四、子组件调用父组件的方法(属性)
1、子组件
bar () { console.log(this.$parent) this.$parent.names.push('张三') }
五、子组件同步修改父组件的值(在属性后面加sync)
1、父组件
<child01 :names="names" v-if="isLoading" @sendVal="sendVal" ref="child" :aa.sync="text"/>
2、子组件
post () { this.$emit('update:aa', '子组件的值') }
六、父组件传递给子组件,子组件又传递给孙组件
常见的方法:
- 1、父传给给子,子传递给孙组件,逐级传递(非常麻烦而且不易于维护的)
- 2、使用
vuex
状态机(杀鸡用牛刀,大材小用) - 3、使用
Vue
提供了【inheritAttrs】
和【attrs】
- 4、使用
provide/inject
进行多级组件值传递
步骤
1、定义一个父组件,传递两个参数到子组件和孙组件
<template> <div> <child02 :text="text" :count="count"/> </div> </template> <script> import child02 from './child02' export default { data () { return { text: '父组件的值', count: 123456 } }, components: { child02 } } </script> <style scoped> </style>
2、子组件
<template> <div> <h2>第二个组件</h2> <div>{{text}}</div> <child03 v-bind="$attrs"/> </div> </template> <script> import child03 from './child03' export default { props: { text: { type: String | Number } }, // 解决父组件传递过来的值,没被使用的情况下挂载在本组件上(类似自定义属性) inheritAttrs: false, components: { child03 }, mounted () { console.log(this.$attrs) } } </script> <style scoped> </style>
3、孙组件
<template> <div> <h3>我是孙组件</h3> </div> </template> <script> export default { mounted () { console.log('我是孙组件', this.$attrs) } } </script> <style scoped> </style>
七、provide/inject
多级组件传递值
1、父组件中使用
provide
(也不需要写属性传递)provide: { parent: '父组件的值====' },
2、在需要使用的子孙组件中使用
export default { inject: ['parent'], mounted () { console.log(this.parent) } }
八、provide/inject
异步创建数据
1、父组件
<template> <div> <child02 :text="text" :count="count" v-if="isLoad"/> </div> </template> <script> import child02 from './child02' export default { provide () { let parent = {} setTimeout(() => { Object.defineProperty(parent, 'value', { get: () => this.text, enumerable: true }) this.isLoad = true }, 1000) return { parent } }, data () { return { text: '父组件的值', count: { name: 'haa' }, isLoad: false } }, mounted () { }, components: { child02 } } </script> <style scoped> </style>
- 2、子组件跟之前的一样
九、混入mixins
的使用
其实这个功能有些类似于
es6
中的Object.assign()
方法。根据一定的规则合并两个配置,常用于抽取相同的地方
1、单独定义一个文件(自动关闭弹框)
export const mixin = { methods: { autoClose () { setTimeout(() => { this.$Modal.remove(); }, 2000); } } }
2、使用
import {mixin} from './../utils/minx' export default { mixins: [mixin], methods: { childClose () { // close在本组件中没有定义,其实就是使用了minx里面的 this.close() } } }
十、非父子组件传递
官方推荐使用
bus
组件,有两种实现方式
方法一(不需要单独创建一个组件)
1、在入口文件中加入
data
new Vue({ el: '#app', router, components: { App }, template: '<App/>', data: { Bus: new Vue() } })
2、发送数据的组件
<button @click="submit">提交</button> ... methods: { submit() { // 事件名字自定义,用不同的名字区别事件 this.$root.Bus.$emit('eventName', 123) }, },
3、接收数据的组件
... created(){ this.$root.Bus.$on('eventName', value => { this.print(value) }) }, methods: { print(value) { console.log(value) } }, // 在组件销毁时别忘了解除事件绑定 beforeDestroy() { this.$root.Bus.$off('eventName') }, ...
方法二(单独创建一个bus.js
)
1、单独创建一个
bus.js
import Vue from 'vue' export default new Vue;
2、在发送数据的组件中
<button @click="bus">bus组件</button> ... import Bus from './bus.js' ... methods: { bus() { Bus.$emit('msg', '我要传递给兄弟组件, 你收到了吗') } },
3、在接收数据的组件中
import Bus from './bus.js' ... mounted() { Bus.$on('msg', (e) => { console.log('我是bar组件', e); }) }